Как повторить тайм-аут ожидания блокировки, используя постоянство Java? - PullRequest
0 голосов
/ 29 июля 2010

Мне нужны некоторые разъяснения о правильном способе повторения «повторного» исключения (например, что-то вроде тайм-аута ожидания блокировки) при использовании постоянства Java. Например, с псевдокодом вроде:

EntityTransaction tx = em.getTransaction();
tx.begin();
for (a bunch of objects) {
  em.persist(object);
}
tx.commit();

Я иногда получаю исключение при вызове em.persist, если в БД есть блокировка. Могу ли я просто обернуть это в попытку / поймать и повторить попытку (очевидно, с некоторым количеством)? Или я должен обернуть весь tx.begin / commit и повторить , что ?

ТНХ

Ответы [ 3 ]

1 голос
/ 29 июля 2010

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

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

0 голосов
/ 18 апреля 2012

До тех пор, пока исключение, выданное EntityManager, не помечает транзакцию как только откат (LockTimeoutException является одним из таких примеров, однако PessimisticLockException нет), вы можете продолжать обрабатывать вещи в текущей транзакции.

Если TX помечен как только откат, вам нужно будет спасти TX, а затем повторить все, что вы пытались - до того, как произошла ошибка в TX, и продолжить.

Если вы собираетесь работать с JPA, возможно, у вас есть хороший кандидат на DELETE или UPDATE jpql-запрос.

0 голосов
/ 29 июля 2010

Если вы программируете в соответствии со спецификацией, вы должны избавиться от всего EntityManager и начать все сначала.Нет никаких исключений, которые гарантированно будут «повторяемыми» на уровне EM.Весь ваш сеанс персистенции считается непоследовательным / неопределенным, если исключение возникает из метода persist ().

Иногда это будет работать.Я знаю, что в спящем режиме вы можете избежать попыток усиления после исключения из оптимистичной блокировки.Но в целом вы полагаетесь на специфическое поведение поставщика, которое может быть плохо определено, если вы попытаетесь перехватить и восстановить после исключений entitymanager и сохранить тот же самый entitymanager.

Подробнее здесь.

...