【发布时间】:2014-02-20 20:16:25
【问题描述】:
当我尝试在多线程环境中创建数据时遇到问题。在调用 super.create() 之前,我检查数据库中是否不存在数据。但我相信线程同时调用方法 create() 并且其中一个线程失败抛出重复键异常而不是 IllegalArgumentException :
@Transactional(readOnly=false)
@Override
public T create(T resource){
//check if data already exists
if(this.repository.findById(resource.getId()) != null){
throw new IllegalArgumentException("Resource already exists");
}
//else call create
return super.create(resource);
}
有什么办法让它起作用吗?该项目使用 spring-data-jpa 和 Hibernate 4.3.1.Final 和 Oracle 数据库
PS:我需要一个比只捕获异常更智能的解决方案,因为我在更新过程中遇到了同样的问题,如果资源日期比当前的更新日期,我必须检查集成日期是否更新资源数据库。
而且我的项目必须在多个节点上运行。
谢谢
【问题讨论】:
-
你使用什么 id 生成策略?
-
嗨,我正在使用序列生成器策略,但重复键实际上不在 id 字段上,上面的代码不完全是我正在使用的代码。实际上,检查是在另一个名为 applicationId (findByApplicationId) 的字段上进行的,它有一个唯一的约束。
-
其他字段的值是否来自用户输入?还是它也生成了?另一个与您目前得到的答案更相关的问题:您是否在集群中运行?如果您有多个节点线程同步将无济于事。
-
价值来自用户输入,是的,我需要运行我的项目的多个实例...
-
通常情况下,可以在集群环境或这种情况下使用身份生成策略。 DB 会自动为你增加 id。
标签: java multithreading hibernate spring-data