Теперь, когда транзакция тайм-аута EJB вызовет разрыв потока бесконечного цикла или контейнер остановит поток, выполняющий цикл infinte.
Этот ответ основан на обратном-инжиниринг, который я выполнил пару лет назад на OC4J 10.3.x, WebSphere 6.x и WebLogic 10.x, и мог бы применяться аналогичным образом к другим контейнерам.Насколько я помню, обнаружение тайм-аута транзакции реализовано по-разному в разных контейнерах, но все они используют определенные общие принципы, изложенные ниже:
- Обнаружение тайм-аута транзакции обычно выполняется в другом потоке, управляемомконтейнер.Соответствующий поток спит в течение указанной продолжительности (обычно 1 секунда), затем просыпается и выполняет итерацию по всем выполняющимся транзакциям.Если какая-либо транзакция превысила указанное время ожидания (обычно на разных уровнях - контейнер JTA, EJB и т. Д.), То поток помечает транзакцию для отката.Не будет предпринято никаких попыток сообщить потоку, выполняющему транзакцию, о состоянии транзакции.
- Когда поток, выполняющий транзакцию, пытается взаимодействовать с координатором JTA или с транзакционным ресурсом (экземпляр
XAResource
)чтобы выполнить некоторую работу (например, выполнить запрос SQL), контейнер определит, что транзакция была помечена для отката, и выдаст TransactionRolledBackException
.
На основании вышеизложенного,можно сделать вывод, что бесконечный цикл никогда не будет разорван, если не будет брошено TransactionRolledBackException
.Другими словами, цикл будет прерван только тогда, когда внутри цикла будет предпринята транзакционная активность;если такие действия не выполняются, то цикл сохранит свое свойство бесконечно долго выполнять.
Обратите внимание, что некоторые контейнеры, такие как WebLogic, позволяют обнаруживать «застрявшие» потоки.Это означает, что такие контейнеры имеют возможность обнаруживать, выполнялся ли поток в течение продолжительного периода времени сверх заданной продолжительности.Это не означает, что контейнер прервет или прервет поток, когда обнаружит, что он застрял.