![](/img/trans.png)
[英]In java spring hibernate 3.6.3 how to tell a method to wait until lock is aqured and how to retry a failed transaction?
[英]How to retry a lock wait timeout using java persistence?
我需要对使用Java持久性时重试“可重试”异常(例如类似锁等待超时之类)的正确方法进行一些说明。 例如,使用伪代码,例如:
EntityTransaction tx = em.getTransaction();
tx.begin();
for (a bunch of objects) {
em.persist(object);
}
tx.commit();
如果数据库中有锁,有时会在em.persist调用中引发异常。 我可以将其包装在try / catch中然后重试吗(很明显,有一些计数)? 还是我必须包装整个tx.begin / commit并重做 ?
谢谢
假设没有锁定超时作为解决数据库死锁的方法,那么一个更简单的解决方案是对请求使用更长的超时。 将超时设置为N * (C + 1)
秒,而不是使用N
秒的超时并重试最多C
次。
(如果您将锁定超时用作死锁的一种解决方法,那么您会遇到更大的问题。您最好尝试解决死锁的根本原因,因为即使使用C
重试,您的交易也有可能获胜不能通过。)
只要EntityManager抛出的异常不会将事务标记为仅回滚(LockTimeoutException是此类示例之一,而PessimisticLockException并非如此),则可以继续处理当前事务中的事务。
如果TX仅被标记为回滚,则您必须对TX进行保释,然后重试TX内发生错误之前的任何尝试,然后继续操作。
如果要通过JPA循环进行工作,那么您很有可能是DELETE或UPDATE jpql查询的候选人。
如果您按照规范进行编程,则实际上应该处置整个EntityManager并重新开始。 没有任何例外可以保证在EM级别“可重试”。 如果persist()方法产生异常,则整个持久性会话将被视为不一致/不确定。
有时它将起作用。 我知道在休眠状态下,您通常可以在乐观锁定异常之后尝试获得收益。 但是总的来说,如果您试图捕获并从entitymanager异常中恢复并保持相同的entitymanager,则您将依赖于供应商特定的行为,这些行为可能定义不清。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.