|
|
|
|
|
|
Re: Why the value of sequence will change after reboot? [message #124622 is a reply to message #124267] |
Mon, 20 June 2005 09:20 |
smartin
Messages: 1803 Registered: March 2005 Location: Jacksonville, Florida
|
Senior Member |
|
|
I think the correct question to be asking is why do you care if you cache a few sequence numbers and lose them when you reboot the server? You aren't going to run out of numbers.
And the reason you cache them is so that you don't have to generate them one at a time, so there can be a performance impact (on an active enough system) using nocache.
|
|
|
|
Re: Why the value of sequence will change after reboot? [message #124767 is a reply to message #124642] |
Tue, 21 June 2005 06:36 |
rushing
Messages: 135 Registered: January 2004 Location: Beijing,China
|
Senior Member |
|
|
My application do these things:
step 1 create a picture named by the (old max number + 1).jpg
step 2 insert the picture into the database
step 3 get the new number created by oracle
step 4 show the picture named by (new number).jpg
After reboot the system, there will be an error because the new number is not equal the old max number + 1 .
|
|
|
|
|
|
|
Re: Why the value of sequence will change after reboot? [message #124868 is a reply to message #124772] |
Tue, 21 June 2005 22:24 |
rushing
Messages: 135 Registered: January 2004 Location: Beijing,China
|
Senior Member |
|
|
Maaher wrote on Tue, 21 June 2005 08:05 |
rushing wrote on Tue, 21 June 2005 10:36 | After reboot the system, there will be an error because the new number is not equal the old max number + 1 .
| Why?
Have you read the links I provided you? I don't see why name_NN must be following name_(NN-1) and must be preceding name_(NN+1). I really don't.
MHE
|
Dear Maahr,
I read your link now, and found it is a serious problem of oracle.
These articles are helpful.
Thanks!
|
|
|
|
|
Re: Why the value of sequence will change after reboot? [message #125108 is a reply to message #125020] |
Thu, 23 June 2005 06:05 |
|
Maaher
Messages: 7065 Registered: December 2001
|
Senior Member |
|
|
Consider rollbacks. Every time a sequence.NEXTVAL is called the no is incrmented, nomatter how your transaction ends.
A small test case. The code below is attached as a SQL*Plus script. Run it yourself.
CREATE TABLE nocache_table(the_id NUMBER)
/
CREATE SEQUENCE nocache_sequence
START WITH 1 INCREMENT BY 1
NOCACHE
/
DECLARE
the_number NUMBER;
BEGIN
-- perform 20 inserts (not all are commited)
FOR i IN 1..20 LOOP
SELECT nocache_sequence.NEXTVAL
INTO the_number
FROM dual;
INSERT INTO nocache_table(the_id)
VALUES ( the_number );
-- randomly commit or rollback
IF MOD(
ROUND( dbms_random.value(1,4) )
, 2
) = 0
THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
END LOOP;
END;
/
SELECT the_id
FROM nocache_table
/
DROP SEQUENCE nocache_sequence
/
DROP TABLE nocache_table
/
See for yourself. The result is clear: there are missing numbers!
And another thing about NOCACHE:
from asktom thread "SEQUENCES" |
and setting nocache is like setting:
fast = false
slow = true
I_want_to_be_as_inefficient_as_possible = Please
|
I repeat my original question: why would it be a problem if there are gaps? It's not likely that you run out of sequence numbers so that can't be the reason.
And have you considered deletes and/or updates of your key column? If they are allowed, you have to create some resequencing mechanism.
If it's a business requirement and you cannot change it (sad but true), a nightly batch assigning consequetive numbers to the records that haven't received one yet could be one way to minimise gaps. ( No 100% foolproof solution )
Another solution, not so user friendly would be a single row table holding the last value and a function returning this value and incrementing it. That way, a lock is placed ( due to the update of the value ) and you're sure that no other user is fiddling with it. You can see immediately that this is not ideal in a multi user environment. ( foolproof, but performance killer in the worst kind of way ). This would be like putting a document in a version control system and each time check it out, add a page and check it back in. Every other user has to wait for the document to become available again. Imagine this at a site like a bank! Marvelous
I have tried entirely different approach: add a timestamp column to your table holding the creation date and place a view on top of the original table, containing ROWNUM sorted by this timestamp column. (See script below)
CREATE TABLE the_table(the_id NUMBER, created_on TIMESTAMP)
/
CREATE VIEW the_view
AS
SELECT ROW_NUMBER() OVER ( ORDER BY created_on ) idx
, the_id
FROM the_table
/
CREATE SEQUENCE nocache_sequence
START WITH 1 INCREMENT BY 1
NOCACHE
/
DECLARE
the_number NUMBER;
BEGIN
-- perform 20 inserts (not all are commited)
FOR i IN 1..20 LOOP
SELECT nocache_sequence.NEXTVAL
INTO the_number
FROM dual;
INSERT INTO the_table(the_id, created_on)
VALUES ( the_number, SYSTIMESTAMP );
-- randomly commit or rollback
IF MOD(
ROUND( dbms_random.value(1,4) )
, 2
) = 0
THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
END LOOP;
END;
/
SELECT the_id
FROM the_table
/
SELECT idx
, the_id
FROM the_view
/
DROP SEQUENCE nocache_sequence
/
DROP view the_view
/
DROP TABLE the_table
/
The view seems to be a nice solution for this "problem". Perhaps this can help you out.
Just my 2 cents...
MHE
[Updated on: Sun, 26 June 2005 09:38] Report message to a moderator
|
|
|
|