我有一个在 5 个应用服务器上运行的分布式 Java 应用程序。这些服务器都使用在第 6 台机器上运行的相同 Oracle 9i 数据库。
应用程序需要从一个序列中预取一批 100 个 ID。在单线程、非分布式环境中执行此操作相对容易,您只需发出以下查询:
SELECT seq.nextval FROM dual;
ALTER SEQUENCE seq INCREMENT BY 100;
SELECT seq.nextval FROM dual;
第一个选择获取应用程序可以使用的第一个序列 ID,第二个选择返回最后一个可以使用的序列 ID。
在多线程环境中,事情变得更加有趣。您不能确定在第二次选择之前,另一个线程不会再次将序列增加 100。这个问题可以通过在 Java 端同步访问来解决——一次只让一个线程开始获取 ID。
当您无法同步时,情况会变得非常困难,因为应用程序的某些部分不在同一个 JVM 上运行,甚至不在同一个物理机器上。我在论坛上发现了一些参考资料,其他人也有解决这个问题的问题,但没有一个答案真的有效,更不用说是合理的了。
社区可以为这个问题提供解决方案吗?
更多信息:
- 我真的不能玩事务隔离级别。我使用 JPA,更改会影响整个应用程序,而不仅仅是预取查询,这对我来说是不可接受的。
在 PostgreSQL 上,我可以执行以下操作:
SELECT setval('seq', NEXTVAL('seq') + n - 1)
当您可以使用固定的增量值(在我的情况下这是完全可以接受的)时,Matthew 的解决方案有效。但是,当您不想固定增量的大小,而是想动态调整它时,是否有解决方案?