I have a distributed Java application running on 5 application servers. The servers all use the same Oracle 9i database running on a 6th machine.
The application need to prefetch a batch of 100 IDs from a sequence. It's relatively easy to do in a single-threaded, non-distributed environment, you can just issue these queries:
select seq.nextval from dual;
alter sequence seq increment by 100;
select seq.nextval from dual;
The first select fetches the first sequence ID that the application can use, the second select returns the last one that can be used.
Things get way more interesting in a multithreaded environment. You can't be sure that before the second select another thread doesn't increase the sequence by 100 again. This issue can be solved by synchronizing the access on the Java side - you only let one thread begin fetching the IDs at one time.
The situation becomes really hard when you can't synchronize because parts of the application doesn't run on the same JVM, not even on the same physical machine. I found some references on forums that others have problems with solving this problem too, but none of the answers are really working not to mention being reasonable.
Can the community provide a solution for this problem?
Some more information:
- I can't really play with the transaction isolation levels. I use JPA and the change would affect the entire application, not only the prefetching queries and that's not acceptable for me.
On PostgreSQL I could do the following:
select setval('seq', nextval('seq') + n - 1 )
The solution by Matthew works when you can use a fixed increment value (which is perfectly acceptable in my case). However is there a solution when you don't want to fix the size of the increment, but want to adjust it dynamically?