我有一个并发问题,我尝试通过while循环来解决,该循环尝试多次保存实体,直到达到某个最大重试次数。我想避免谈论是否还有其他方法可以解决此问题。我还有其他关于此的Stackoverflow帖子。:)长话短说:在派生的列上有一个唯一约束,其中包括一个数字部分,该数字部分不断增加以避免冲突。在一个循环中,我:
除了循环返回到步骤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,但是没有直接访问实体管理器的权限。我想我可以在需要时注射它,但这对这个问题是一个痛苦的解决方案。
DataAccessException
您无法执行此操作- 刷新某些内容后,如果失败并且抛出异常,则该事务将被标记为回滚。这意味着捕获异常并继续操作并不重要,最终将导致回滚。实际上,抛出什么异常根本没有关系- 默认情况下,Spring的事务管理器将回滚每个 未检查的 异常。您可以通过noRollbackFor在@Transactional注释上专门定义a来克服它(假设您正在使用注释驱动程序事务)
noRollbackFor
@Transactional
编辑-如果违反此约束,它也无济于事,因为该事务可能会在数据库级别标记为回滚。