Как обрабатывать исключение javax.persistence.OptimisticLockException? - PullRequest
7 голосов
/ 07 февраля 2010

Я новичок в 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();
    }
}

У меня вопрос, как вы решаете, когда прекратить повторные попытки?

1 Ответ

10 голосов
/ 07 февраля 2010

У меня вопрос, как вы решаете, когда прекратить повторные попытки?

На мой взгляд, Оптимистическая блокировка должна использоваться, когда модификация одного и того же объекта в одно и то же время является исключительной ситуацией.

Теперь, если такая ситуация возникает, и если процесс был ручным, я предупреждаю пользователя о том, что изменения не удалось сохранить, и просил его сохранить свои изменения снова.

Если процесс автоматизирован, может иметь смысл реализовать механизм автоматической повторной попытки, но я бы не стал повторять более чем три или пять раз, в зависимости от времени обработки (и я бы использовал рекурсивные вызовы для реализации этого ). Если автоматизированный процесс 5 раз подряд дает сбой из-за проблемы одновременного доступа, то он, скорее всего, конкурирует с другим автоматизированным процессом, и они либо не работают с независимыми порциями данных (что плохо для распараллеливания), либо стратегия просто не работает правый. В обоих случаях повторная попытка больше не является правильным решением.

...