i have a persistent hibernate managed @entity Obj in Hibernate, which has fields id, fieldA, and fieldB, among others.
我在hibernate中有一个持久的hibernate托管@entity Obj,它有字段id、fieldA和fieldB等。
In some class i have two @Transactional methods, updateA() and updateB().
updateA() obtains an Obj by its id, does some processing, and updates its fieldA.
updateB does same for fieldB.
在某些类中,我有两个@Transactional方法:updateA()和updateB()。updateA()通过其id获取Obj,进行一些处理,并更新其fieldA。updateB对fieldB也这样做。
I also have two clients that continuously make requests. One client always makes requests that call updateA(), and the other client always calls updateB().
They both pass the same id of an existing Obj.
我也有两个客户不断地提出请求。一个客户机总是发出调用updateA()的请求,而另一个客户机总是调用updateB()。它们都传递现有Obj的相同id。
Is there a way to avoid the HibernateOptimisticLockingFailureException that keeps occurring, or to handle it once successfully, given the fact that each method updates different fields? Some kind of a merge?
有什么方法可以避免经常发生的HibernateOptimisticLockingFailureException,或者在每个方法更新不同字段的情况下成功地处理它吗?某种合并?
Just to complete the picture, the thread that calls updateA() in fact calls other transactional methods similar to updateA(), but none updates fieldB.
为了完成这幅图,调用updateA()的线程实际上调用与updateA()类似的其他事务方法,但没有一个线程更新fieldB。
At first I just tried to catch the exception and re-try the operation a second time. But sometimes it fails the second time too... This does not seem like a good solution.
起初,我只是试图捕获异常,然后再次尝试操作。但有时第二次也失败了……这似乎不是一个好的解决方案。
2 个解决方案
#1
1
If you can safely do it, the easiest way is to exclude fieldB
from optimistic locking:
如果您可以安全地进行此操作,最简单的方法是将fieldB排除在乐观锁定之外:
import org.hibernate.annotations.OptimisticLock;
/* ... */
@OptimisticLock(excluded=true)
private B fieldB;
#2
1
You can use an automatic optimistic locking retry mechanism.
您可以使用自动乐观锁定重试机制。
For that you need to add the following dependency:
为此,您需要添加以下依赖项:
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>db-util</artifactId>
<version>0.0.1</version>
</dependency>
Then just mark your service methods with the following annotation:
然后用以下注释标记您的服务方法:
@Retry(times = 5, on = OptimisticLockException.class)
#1
1
If you can safely do it, the easiest way is to exclude fieldB
from optimistic locking:
如果您可以安全地进行此操作,最简单的方法是将fieldB排除在乐观锁定之外:
import org.hibernate.annotations.OptimisticLock;
/* ... */
@OptimisticLock(excluded=true)
private B fieldB;
#2
1
You can use an automatic optimistic locking retry mechanism.
您可以使用自动乐观锁定重试机制。
For that you need to add the following dependency:
为此,您需要添加以下依赖项:
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>db-util</artifactId>
<version>0.0.1</version>
</dependency>
Then just mark your service methods with the following annotation:
然后用以下注释标记您的服务方法:
@Retry(times = 5, on = OptimisticLockException.class)