java - 如何在分布式环境中预取 Oracle 序列 ID

标签 java oracle

我有一个在 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,更改会影响整个应用程序,而不仅仅是预取查询,这对我来说是 Not Acceptable 。
  • 在 PostgreSQL 上,我可以执行以下操作: SELECT setval('seq', NEXTVAL('seq') + n - 1)

  • Matthew 的解决方案在您可以使用固定增量值时有效(在我的情况下完全可以接受)。但是,当你不想固定增量的大小,而是想动态调整它时,有什么解决方案吗?

最佳答案

为什么不让序列一直递增 100?每个“nextval”给你 100 个序列号来处理

SQL> create sequence so_test start with 100 increment by 100 nocache;

Sequence created.

SQL> select so_test.nextval - 99 as first_seq, so_test.currval as last_seq from dual;

 FIRST_SEQ   LAST_SEQ
---------- ----------
         1        100

SQL> /

 FIRST_SEQ   LAST_SEQ
---------- ----------
       101        200

SQL> /

 FIRST_SEQ   LAST_SEQ
---------- ----------
       201        300

SQL> 

关于你的例子的注释..注意 DDL..它会产生隐式提交

DDL 生成的提交示例

SQL> select * from xx;

no rows selected

SQL> insert into xx values ('x');

1 row created.

SQL> alter sequence so_test increment by 100;

Sequence altered.

SQL> rollback;

Rollback complete.

SQL> select * from xx;

Y
-----
x

SQL> 

关于java - 如何在分布式环境中预取 Oracle 序列 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43808/

相关文章:

oracle - 在sql plus脚本中运行循环

mysql - 迁移localhost MySQL到AWS Oracle好像要等四个小时

java - 如何创建具有特定大小但仍具有硬件控制按钮的 ADT 虚拟机?

java - 如何以最简单的方式将AsyncTask切换到Loader?

Java,为什么这个文本没有在直列中对齐?

java - 如何在 eclipse java 应用程序中添加 java 参数以及类路径?

Oracle 11 查询在前 2 次执行时运行速度快,后续运行速度较慢,没有计划更改

java - jdbc url 定义

sql - 从 oracle 过程返回 Json 字符串

java - LayoutInflater 膨胀 fragment