Forum OpenACS Q&A: Response to Nextval from dual foolproof?

Collapse
Posted by Don Baccus on
"nextval" is guaranteed, in Oracle as well as Postgres, to return a unique value, and "currval" the current value for the sequence in YOUR  context.

Let's say process A does a nextval and gets 1
process B does a nextval and gets 2
process A does a currval and gets 1
process A does a nextval and gets 3

The thing you CAN'T depend on is nextval being one greater than currval.

You can't do a currval before a nextval (because you must aquire a sequence value before currval is set for your context).

This also means that code like:

insert into foo value (nextval('sequence_name'), ...);
insert into foo_related (currval('sequence_name'), ...);

guarantees that the value derived from the sequence is the same.  There's no need for you to do any explicit locking on the sequence or anything screwy like that.

The other thing you're asking about is that the pages allocate an id from a sequence early, in the form page rather than the script that services the POST from the form.  If the response time is slow (this is the internet, remember? :) the user might get think that nothing's happening and click "submit" the same.  Since the form page has allocated the id, this will result in a POST with the same id value being passed to the second page.  When this is inserted into the database, an exception will be raised because the first page handling the post will have already inserted the value (well, we have a race condition so we don't really know which "click" gets processed first, but we don't care).

If the page processing the POST allocated the ID from the sequence, the script handling the POST would allocate two differnet ids, and insert whatever it builds from the form, with no error since the ids wouldn't violate the primary key uniqueness requirement.  So, for instance, your bulletin board post or ad or whatever would show up twice.

The double-click code helps to prevent this.