小编典典

JPA并发问题“在发布批处理时,它仍然包含JDBC语句”

hibernate

我有一个并发问题,我尝试通过while循环来解决,该循环尝试多次保存实体,直到达到某个最大重试次数。我想避免谈论是否还有其他方法可以解决此问题。我还有其他关于此的Stackoverflow帖子。:)长话短说:在派生的列上有一个唯一约束,其中包括一个数字部分,该数字部分不断增加以避免冲突。在一个循环中,我:

  1. 选择最大(some_value)
  2. 增加结果
  3. 尝试使用此新结果保存新对象
  4. 显式刷新实体,如果由于唯一索引而失败,则捕获DataAccessException。

除了循环返回到步骤1并尝试选择时,所有这些似乎都有效,我得到:

17:20:46,111 INFO  [org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl] (http-localhost/127.0.0.1:8080-3) HHH000010: On release of batch it still contained JDBC statements
17:20:46,111 INFO  [my.Class] (http-localhost/127.0.0.1:8080-3) MESSAGE="Failed to save to database. Will retry (retry count now at: 9) Exception: could not execute statement; SQL [n/a]; constraint [SCHEMA_NAME.UNIQUE_CONSTRAINT_NAME]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement"

并且捕获了一个新的异常。似乎是第一次刷新会导致唯一约束违例并抛出,DataAccessException不会清除实体管理器的批处理。解决这个问题的合适方法是什么?我在JPA上使用Spring,但是没有直接访问实体管理器的权限。我想我可以在需要时注射它,但这对这个问题是一个痛苦的解决方案。


阅读 1149

收藏
2020-06-20

共1个答案

小编典典

您无法执行此操作-
刷新某些内容后,如果失败并且抛出异常,则该事务将被标记为回滚。这意味着捕获异常并继续操作并不重要,最终将导致回滚。实际上,抛出什么异常根本没有关系-
默认情况下,Spring的事务管理器将回滚每个 未检查的
异常。您可以通过noRollbackFor@Transactional注释上专门定义a来克服它(假设您正在使用注释驱动程序事务)

编辑-如果违反此约束,它也无济于事,因为该事务可能会在数据库级别标记为回滚。

2020-06-20