2014-09-29 140 views
1

我有一个持久的hibernate管理@entity Obj在休眠,其中有字段id,fieldA和fieldB,等等。有没有办法避免HibernateOptimisticLockingFailureException?

在某些类中,我有两个@Transactional方法updateA()和updateB()。
updateA()通过它的id获得一个Obj,做一些处理,并更新它的fieldA。
updateB对fieldB做相同的操作。

我也有两个客户不断提出请求。 一个客户端总是发出调用updateA()的请求,而另一个客户端总是调用updateB()。
他们都通过一个现有的Obj相同的ID。

有没有办法避免HibernateOptimisticLockingFailureException一直发生,或一旦成功处理它,因为每个方法更新不同的字段?某种合并?

只是为了完成图片,调用updateA()的线程实际上调用了与updateA()类似的其他事务方法,但没有更新fieldB。

起初,我只是试图捕捉异常,并重新尝试第二次操作。但有时它也会第二次失败......这似乎不是一个好的解决方案。

+0

您正在使用的版本('@ Version')您实体? – 2014-09-29 04:36:47

+0

不使用@Version。如果两个客户端同时更新fieldB,将读取它 – inor 2014-10-01 04:57:04

回答

1

如果你可以安全地做到这一点,最简单的方法是从乐观锁定排除fieldB

import org.hibernate.annotations.OptimisticLock; 

/* ... */ 

@OptimisticLock(excluded=true) 
private B fieldB; 
+0

不会失败吗? – 2014-09-29 04:46:04

+0

@ThomasStets以什么方式失败? – 2014-09-29 04:47:13

+0

好吧,我错过了他只有一个客户更新fieldB的事实。但是,如果有更多的客户端可以在没有Hibernate注意的情况下覆盖另一个客户端的更新。 – 2014-09-29 04:52:01

1

您可以使用automatic optimistic locking retry mechanism

对于您需要添加以下依赖:

<dependency> 
    <groupId>com.vladmihalcea</groupId> 
    <artifactId>db-util</artifactId> 
    <version>0.0.1</version> 
</dependency> 

然后,只需标记与以下标注你的服务的方法:在

@Retry(times = 5, on = OptimisticLockException.class) 
相关问题