EJB: избегать отмены транзакции
Когда (транзакционный) метод EJB вызывает другой (транзакционный) метод другого EJB, а исключение генерируется во втором, но в первом случае оно кажется, что транзакция автоматически откатывается, когда вторая один возвращается, даже если первый поймал его, это правда? как я могу его избежать?
Сценарий следующий:
@Stateless
class ClassA {
@EJB
ClassB objectB;
methodA() {
try {
objectB.methodB();
}
catch(Exception e) {
//Here the transaction started in this method is
//automatically rolled back. Is this avoidable?
}
}
}
@Stateless
class ClassB {
methodB() throws Exception { throw new Exception() }
}
Ответы
Ответ 1
Транзакция отменяется в случае, если вы выбрали RuntimeException
или любое исключение с аннотацией @ApplicationException
с атрибутом rollback
, установленным на true
, поэтому:
@ApplicationException(rollback=true)
public class MyException extends Exception {
// ...
}
отменит текущую транзакцию.
По умолчанию ApplicationException не откатывает транзакцию.
Если вы не хотите, чтобы методB отменил транзакцию, вы можете либо изменить поведение отката вашего ApplicationException
, либо предотвратить совместное использование транзакций.
Последнее возможно, изменив TransactionAttribute
метода B, т.е. на RequiresNew
. Тогда транзакция methodA (Tx1) будет приостановлена, и в случае, когда методB выдает исключение, которое приводит к откату его транзакции (Tx2), вы все равно можете поймать его в методе A и предотвратить откат транзакции methodA (Tx1).
Ответ 2
Да, это правда, если исключение является исключением. Проверенные исключения не вызывают откат транзакции.
Чтобы избежать этого, просто убедитесь, что код в methodB
не выбрасывает исключение во время выполнения. Исключение во время выполнения обычно указывает на ошибку или состояние, которое не позволяет продолжить работу.