Spring вложенный метод @Transactional и откат - PullRequest
7 голосов
/ 10 ноября 2011

У меня есть класс @Service, у которого есть метод @Transactional, который вызывает другой метод @Transactional в том же классе. Я тестировал поведение отката для этого и обнаружил, что он не работает должным образом. Код выглядит примерно так:

@Service
public class DefaulService implements ervice
{
    @Transactional
    public void methodOne()
    {
        methodTwo();

            //question edited
            //this seems to be the problem
            this.serviceDAO.executeUpdateOperation();

        //test rollback
        throw new RuntimeException();
    }

    @Transactional
    public void methodTwo()
    {
        //DAO stuff
    }
}

После запуска methodOne я проверяю базу данных и есть ли в ней изменения, хотя в журнале отображается «JDBCTransaction - rollback».

Если я вызову methodTwo индивидуально и добавлю исключение в конце, изменения будут отменены правильно.

Есть ли способ заставить methodOne правильно откатить изменения, произошедшие во время вложенного вызова @Transactional? У меня сложилось впечатление, что распространение REQUIRED по умолчанию достигнет этого, но, похоже, оно не работает. Спасибо

UPDATE

Хорошо, я только что заметил кое-что еще. Прямо перед выдачей исключения я вызываю службу dao и выполняю обновление вручную с помощью executeUpdate. Если я прокомментирую эту строку, вложенный откат будет работать. Таким образом, похоже, что проблема на самом деле вызывает DAO и выполняет запрос executeUpdate. Но не должно ли это также выполняться внутри текущей транзакции?

1 Ответ

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

Вы определенно получаете экземпляр "ervice" из фабрики бинов, когда вызываете методы, верно? Фабрике бинов необходимо настроить прокси, который реализует транзакционную логику вокруг каждого вызова метода. У меня сложилось впечатление, что это работает только тогда, когда «посторонние» вызывают методы через прокси, и не обязательно работает, когда один метод вызывает другой, так как этот метод является прямым вызовом внутри объекта реализации и не проходит через прокси AOP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...