Java 集群环境下的并发事务问题

Java 集群环境下的并发事务问题,java,concurrency,transactions,jvm,optimistic-locking,Java,Concurrency,Transactions,Jvm,Optimistic Locking,我在运行于集群环境的web应用程序中遇到了一个场景 我们有2个节点(都有JVM) 节点1 节点2 我正在我的应用程序中运行一个数据库事务,其中读取序列号,然后我们用加1的方式递增它 select sequence from some_table; nextsequence = sequence + 1; // incrementing sequence update some_table set sequence = nextsequence; // set the next seque

我在运行于集群环境的web应用程序中遇到了一个场景

我们有2个节点(都有JVM)

  • 节点1
  • 节点2
  • 我正在我的应用程序中运行一个数据库事务,其中读取序列号,然后我们用加1的方式递增它

    select sequence from some_table;
    
    nextsequence = sequence + 1; // incrementing sequence 
    
    update some_table set sequence = nextsequence;  // set the next sequence
    
    现在发生的事情请求转到Node1,并增加序列号。但由于Node1上的outofmemoryerror,请求被缓慢提交到数据库(需要1分钟)。同时,另一个请求转到Node2,从数据库中获取序列号并更新它。所以这两个请求都有相同的序列,我们不需要,因为我们希望所有请求都有唯一的序列号

    我们无法同步事务,因为它运行在不同的JVM上,因此没有帮助


    我想知道下一步该怎么办?非常感谢您提供的任何帮助。

    如果您不能像许多评论所建议的那样在数据库中进行控制,那么您的下一个选择就是实现某种形式的简单版本控制

    一种方法是将update语句更改为:

    update some_table set sequence = nextsequence where sequence = [sequence you just read];
    

    然后查看更新了多少条记录(例如,PreparedStatement的executeUpdate()将给出此值)。如果结果为0,那么您的流程的另一个实例将击败您,因此您以某种方式处理它(抛出并出错,选择另一个序列号,…)

    您使用的是哪个数据库?任何主要的数据库支持排序(插入或触发等)-您不应该自己实现它!我们正在使用Oracle 11g。我知道自己实现序列是不好的方法,但这是我需要修复的现有代码。使用数据库序列,或者至少在读取序列时使用悲观锁(选择进行更新)。您不能实现oracle序列并替换检索序列的代码来调用它吗?很明显,您已经有了数据库连接。您的记录主键毕竟不需要是连续的。您可以跳过它们的值,只要它们是唯一的,并且您可以解决两个问题。1.执行不力,2。您的并发问题:)嗯,很奇怪,但注意到了。如果您下定决心要走这条路,那么可以使用乐观并发控制技术。因此,您只能在序列与您期望的序列匹配时更新序列,或者您可以通过存储上次更新序列的时间戳并执行类似检查来实现这一点。如果它们匹配,提交更改,否则抛出异常,返回应用程序,让它检索新序列并重新尝试。