Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何处理多个JVM的并发插入?_Java_Spring Data Jpa_Spring Transactions_Concurrentmodification_Distributed Transactions - Fatal编程技术网

Java 如何处理多个JVM的并发插入?

Java 如何处理多个JVM的并发插入?,java,spring-data-jpa,spring-transactions,concurrentmodification,distributed-transactions,Java,Spring Data Jpa,Spring Transactions,Concurrentmodification,Distributed Transactions,我们有一个Spring引导应用程序,它有一个从客户机调用并与DB交互的控制器类。根据条件,控制器检查是否存在唯一值的记录,如果不存在,则创建一个新记录(使用自动生成的主键)并保存它 现在并发问题出现在这种情况下: A类的两个不同对象想要一个值为b1的B类对象,这两个对象在数据库中同时检查,它们得到null,现在它们试图创建一个值为b1的B类的新对象,出现错误 我试过使用简单的双重锁定方法 final static Object lock = new Object(); public Objec

我们有一个Spring引导应用程序,它有一个从客户机调用并与DB交互的控制器类。根据条件,控制器检查是否存在唯一值的记录,如果不存在,则创建一个新记录(使用自动生成的主键)并保存它

现在并发问题出现在这种情况下:

A类
的两个不同对象想要一个值为
b1
B类
对象,这两个对象在数据库中同时检查,它们得到
null
,现在它们试图创建一个值为
b1
B类
的新对象,出现错误

我试过使用简单的双重锁定方法

final static Object lock = new Object();

public Object handle(cs cs, Map<String, Object> headers){
    LOGGER.info(" persisting message : " + cs.getcsCode());

    F f = repo.findByQuery();
    if (f==null ) {
        synchronized(lock) {
            f = repo.findByQuery;

            if (f==null ) {
                repo.save(cs.getF1());
            }
        }
    }

    return csRepo.save(cs);
}
final static Object lock=new Object();
公共对象句柄(cs、映射头){
info(“持久化消息:+cs.getcsCode());
F=repo.findByQuery();
如果(f==null){
已同步(锁定){
f=repo.findByQuery;
如果(f==null){
repo.save(cs.getF1());
}
}
}
返回csRepo.save(cs);
}
但后来意识到我的应用程序运行在两个JVM上,它们使用一个公共数据库。在讨论了一些问题之后,我想到了另一个选择

@传输(隔离=可重复读取)


但我不确定它是否能在我的场景中工作,正如它的解释所说,它在修改行上的数据时很有用,但我正在创建一个新行。由于这是一个罕见的场景,并且涉及多个JVM,因此我无法确定是否测试它。

重新设置此可重复读取是不够的。您的事务需要可序列化的隔离级别。它是否足够或需要其他东西来处理两个JVM?我还没有使用可序列化的隔离级别。但是阅读描述我会说,哪一个VM打开这样一个事务并不重要。因此,据我所知,您甚至可以在一个VM中打开两个这样的事务来测试它。是否不可能对对应于
类B
的数据库表设置唯一约束,让重复插入失败,并捕获并处理代码中的
ConstraintViolationException
?为什么在查询
repo.findByQuery()
中用于查找记录
f
的键在数据库架构中没有标记为唯一的?由于检查唯一性,其他插入将失败。