hibernate - 如何解决jpa存储库保存方法中的多线程
问题描述
我使用 spring data jpa 来保存实体。
我尝试在这里以不同的方式保存它。
我是多线程的,我运行 save() 方法,所以我注意到有些 save() 有效,但有些 save() 无效。
下面是我的代码。
private static final Executor EXECUTOR = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
/**
* @param book
*/
@Transactional
public void multipleSave(final Book book) {
IntStream.range(0, 2).forEach(index -> EXECUTOR.execute(() -> {
log.info("(1) current thread name :: {}", Thread.currentThread().getName());
Optional<Book> optional = bookJpaRepository.findById(book.getId());
if(optional.isPresent()) {
optional.get().update(book);
return;
}
bookJpaRepository.save(book);
log.info("(2) current thread name :: {}", Thread.currentThread().getName());
}));
}
下面的错误信息
Exception in thread "pool-1-thread-38" org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [book.PRIMARY]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
...java
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
at
....
Caused by: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry '130' for key 'book.PRIMARY'
- 这是保存实体时的关键冲突
- 在我看来,我通过findById确认没有数据,另一方线程似乎正在对entityManger进行刷新以将数据放入db,导致键值冲突。
那么如何解决这个问题..?
给我任何意见,我会参考它。
谢谢。
解决方案
推荐阅读
- javascript - 如何将dataLabels定位在highcharts中arearange图表的中点?
- apache-spark - 将窗口函数应用于多列
- reactjs - 为什么我的状态在获取数据后没有更新?
- laravel - L5 Swagger - 如何为请求正文或响应正文添加示例
- perforce - 强制如何提交标记为“在头部修订时删除”的文件
- c++ - 尽管项目设置,VS2019 未选择 C++17
- php - 如何使用字符串变量访问静态常量
- jmeter - Jmeter如何在30分钟后从0增加到1500
- node.js - Node.js 在本地工作,但在 Heroku 上一次不行
- python - 我无法使用cherrypy检索cookie:有什么问题?