Spring Bean зависает от метода с помощью @Transactional - PullRequest
4 голосов
/ 17 ноября 2011

Просто немного предыстории, я новый разработчик, который недавно принял крупный проект после того, как старший разработчик покинул компанию, прежде чем я смог понять, как он это структурировал.Я постараюсь объяснить мою проблему как можно лучше.

Это приложение создает несколько потоков MessageListner для чтения объектов из очередей JMS.Как только объект получен, данные обрабатываются на основе некоторой бизнес-логики, а затем сопоставляются с постоянным объектом для сохранения в базе данных Oracle с помощью hibernate EntityManager.

До тех пор, пока несколько недель назад не былолюбые серьезные проблемы с этой конфигурацией в прошлом году или около того с тех пор, как я присоединился к проекту.Но для одной из очередей (проблема изолирована от этой конкретной очереди) управляемый компонент Spring, который обрабатывает полученный объект, зависает в методе ниже.Моя отладка привела меня к выводу, что она завершила все в методе, но зависает после завершения.После нескольких недель попыток решить эту проблему, я дошел до конца своей проблемы.Любая помощь с этим будет принята с благодарностью.

Поскольку каждый MessageListner получает свой собственный процессор, этот метод зависания влияет только на входящие данные в одной очереди.

@Transactional(propagation = Propagation.REQUIRES_NEW , timeout = 180)
 public void update(UserRelatedData userData, User user,Company company,...)
 { 
   ...
   ....
   //business logic performed on user object
   ....
   ......
   entityMgr.persist(user);

   //business logic performed on userData object
   ...
   ....
   entityMgr.persist(userData);

   ...
   ....

   entityMgr.flush();

}

Я вставил операторы отладки просто для обхода метода, и он завершает все, включаяentityMgr.flush. ().

Ответы [ 4 ]

4 голосов
/ 17 ноября 2011

Проблемы такого рода могут проявляться, когда базовая база данных блокируется от незафиксированных изменений.

Я подозреваю, что какой-то другой код вставляет / удаляет в таблицах пользовательских данных вне транзакции или в транзакции, выполнение которой занимает очень много времени, поскольку это пакетное задание или подобное.Вы должны проанализировать весь код, ссылающийся на эти таблицы, и найти недостающий @Transactional.

3 голосов
/ 05 августа 2017

REQUIRES_NEW может зависать в контексте теста, потому что менеджер транзакций, используемый в модульном тестировании, не поддерживает вложенные транзакции ... Из Javadoc JpaTransactionManager:

* <p>This transaction manager supports nested transactions via JDBC 3.0 Savepoints.
 * The {@link #setNestedTransactionAllowed "nestedTransactionAllowed"} flag defaults
 * to {@code false} though, since nested transactions will just apply to the JDBC
 * Connection, not to the JPA EntityManager and its cached entity objects and related
 * context. You can manually set the flag to {@code true} if you want to use nested
 * transactions for JDBC access code which participates in JPA transactions (provided
 * that your JDBC driver supports Savepoints). <i>Note that JPA itself does not support
 * nested transactions! Hence, do not expect JPA access code to semantically
 * participate in a nested transaction.</i>

Так ясно, если вы не звоните (@Java config) или не устанавливаете эквивалентный флаг в вашей конфигурации XML:

txManager.setNestedTransactionAllowed(true);

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

1 голос
/ 08 ноября 2012

К сожалению, у меня такая же проблема с Propagation.REQUIRES_NEW. Удаление этого решает проблему. Отладчик показывает мне, что метод фиксации зависает (вызывается из @Transactional аспектной реализации).

Проблема возникает только в контексте тестовой пружины, когда приложение развертывается на сервере приложений, оно работает нормально.

1 голос
/ 17 ноября 2011

Помимо этого ответа , вы также можете проверить уровень изоляции вашей транзакции - возможно, он слишком ограничительный.исключение по истечении времени ожидания?

...