java 应该如何处理 javax.persistence.OptimisticLockException?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2215919/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How should one handle a javax.persistence.OptimisticLockException?
提问by Jacques René Mesrine
I'm new to JPA so forgive me if not being clear.
我是 JPA 的新手,所以如果不清楚,请原谅我。
Basically I want to prevent concurrent modifications by using Optimistic Locking. I've added the @Version attribute to my entity class.
基本上我想通过使用乐观锁定来防止并发修改。我已将 @Version 属性添加到我的实体类中。
I need to know if this algorithm on handling OptimisticLockException is sound. I'm going to use the Execute Around Idiomlike so:
我需要知道这个处理 OptimisticLockException 的算法是否合理。我将像这样使用Execute Around Idiom:
interface UpdateUnitOfWork
{
doUpdate( User user ); /* may throw javax.persistence.PersistenceException */
}
public boolean exec( EntityManager em, String userid, UpdateUnitOfWork work)
{
User u = em.find( User, userid );
if( u == null )
return;
try
{
work.doUpdate( u );
return true;
}
catch( OptimisticLockException ole )
{
return false;
}
}
public static void main(..) throws Exception
{
EntityManagerFactory emf = ...;
EntityManager em = null;
try
{
em = emf.createEntityManager();
UpdateUnitOfWork uow = new UpdateUnitOfWork() {
public doUpdate( User user )
{
user.setAge( 34 );
}
};
boolean success = exec( em, "petit", uow );
if( success )
return;
// retry 2nd time
success = exec( em, "petit", uow );
if( success )
return;
// retry 3rd time
success = exec( em, "petit", uow );
if( success )
return;
}
finally
{
em.close();
}
}
The question I have is how do you decide when to stop retrying ?
我的问题是您如何决定何时停止重试?
回答by Pascal Thivent
The question I have is how do you decide when to stop retrying ?
我的问题是您如何决定何时停止重试?
In my opinion, Optimistic Locking should be used when modifying the same object in the same time is an exceptional situation.
在我看来,当同时修改同一个对象是一种特殊情况时,应该使用乐观锁。
Now, if this situation occurs, and if the process was manual, I would warn the user that the modifications couldn't be saved and ask him to save his changes again.
现在,如果发生这种情况,并且该过程是手动的,我会警告用户无法保存修改并要求他再次保存更改。
If the process is automated, it can make sense to implement an automatic retry mechanism but I wouldn't retry more than something like 3 or 5 times, depending on the processing time (and I'd use recursive calls to implement this). If an automated process fails 5 times in a row on an concurrent access problem, then it is very likely competing with another automated process and they are either not working on independent chunks of data (which is bad for parallelization) or the strategy is just not the right one. In both case, retrying more is not the right solution.
如果流程是自动化的,那么实现自动重试机制是有意义的,但我不会重试超过 3 或 5 次,具体取决于处理时间(我会使用递归调用来实现这一点)。如果一个自动化进程在并发访问问题上连续失败 5 次,那么它很可能与另一个自动化进程竞争,它们要么不处理独立的数据块(这对并行化不利)要么策略就是不正确的那一个。在这两种情况下,重试都不是正确的解决方案。

