Как отловить исключение, выброшенное внутри JTA-транзакции? - PullRequest
2 голосов
/ 24 февраля 2012

Я использую Spring 3.0.5, Hibernate 3.6.7 и Atomikos Transactionessentials 3.7.0.Транзакции, настроенные с использованием AOP в applicationContext.xml.Все просто отлично работает.(commit, rollback)

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

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

Как я могу получить свое собственное исключение вне транзакции?

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

Конкретное исключение (также может быть некоторым стандартным исключением):

public class MySpecialException extends Exception {
    public MySpecialException(String someInfo) {
        super(someInfo);
    }
}

Интерфейс, объявляющий метод, который объявляет, что выдается исключение:

public interface MyInterface {
    Object someJtaTransactionMethod(String param) throws MySpecialException;
}

Класс, реализующий интерфейс:

public class MyClass implements MyInterface {
    Object someJtaTransactionMethod(String param) throws MySpecialException {

        // some operations with some errorstate detected
        // so throw the exception:
        throw new MySpecialException("Things went terribly wrong!");

        // some other code
    }
}

И некоторый код, который вызывает функцию и перехватывает исключения.

public class Caller {

    @Autowired
    private MyInterface callee;

    public void test() {
        try {
            callee.someJtaTransactionMethod("Some test");
        } catch (MySpecialException mex) {
            // I want to get here
        } catch (Exception ex) {
            // but I only get here
        }
    }
}

Возможно ли это вообще?

ОБНОВЛЕНИЕ: Конечно, я взглянул на причину исключения.Само исключение относится к org.springframework.transaction.UnexpectedRollbackException.Причина имеет класс javax.transaction.RollbackTransaction и имеет причину com.atomikos.icatch.RollbackException.

Я думаю, что случается так, что atomikos замечает исключение и выполняет откат (по желанию), но затемAtomikos (возможно, и другие jta-реализации) выдает исключение, указывающее, что транзакция была отменена (неожиданно) и мое исключение пропало.

ОБНОВЛЕНИЕ 2: Забавно, что если я ничего не сделалэто нужно откатить, я могу поймать мое исключение по желанию!

ОБНОВЛЕНИЕ 3 и РЕШЕНИЕ: JB Nizet указал мне на решение.Фактически, моя транзакция не была отменена, как я и подозревал, но из-за причины, по которой я выбросил свое исключение, я получил нарушение, и, следовательно, atomikos выдал свое исключение при коммите.Теперь, когда я настроил транзакцию на откат для моих исключений, все работает как положено и желательно.

Ответы [ 2 ]

4 голосов
/ 24 февраля 2012

Является ли ваше исключение исключением времени выполнения или проверенным исключением?

Откаты по умолчанию по умолчанию, если выбрасывается исключение во время выполнения, и фиксируются по умолчанию, если выбрасывается проверенное исключение.

Из трассировки стека кажется, что ваше исключение является проверенным исключением, поэтому Spring пытается зафиксировать, но не может, потому что JTA TM (Atomikos) отказывается от фиксации (например, из-за тайм-аута).

Итак, если вы хотите, чтобы это исключение вызывало откат, сделайте его исключением во время выполнения или объявите его в атрибуте rollbackFor аннотации @Transactional.Если это не должно вызывать откат, попытайтесь выяснить, почему Atomikos отказывается от фиксации (слишком короткое время ожидания, что-то еще ... журналы могут помочь).

0 голосов
/ 24 февраля 2012

Выглядит как тип для меня, когда вы генерируете MySpecialException, который наследуется от Exception вместо MyException?

В противном случае перехватывает MySpecialException вместо MyException.

...