7

我是 JPA 的新手,如果不清楚,请原谅我。

基本上我想通过使用乐观锁定来防止并发修改。我已将 @Version 属性添加到我的实体类中。

我需要知道这个处理 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();
    }
}

我的问题是您如何决定何时停止重试?

4

1 回答 1

10

我的问题是您如何决定何时停止重试?

在我看来,当同时修改同一个对象是一种例外情况时,应该使用乐观锁定。

现在,如果发生这种情况,并且该过程是手动的,我会警告用户无法保存修改并要求他再次保存更改。

如果该过程是自动化的,那么实现自动重试机制是有意义的,但我不会重试超过 3 或 5 次,具体取决于处理时间(我会使用递归调用来实现这一点)。如果一个自动化进程在并发访问问题上连续失败 5 次,那么它很可能与另一个自动化进程竞争,并且它们要么没有处理独立的数据块(这对并行化不利),要么策略只是没有正确的那一个。在这两种情况下,重试更多都不是正确的解决方案。

于 2010-02-07T06:11:39.517 回答