Шов @ Транзакционная аннотация не работает? - PullRequest
3 голосов
/ 27 октября 2011

Я использую аннотацию @Transactional для компонента шва, похожего на:

@Name( "myComponent" )
@AutoCreate
public class MyComponent
{
    public void something() {
        ...
        doWork();
    }
    ...
    @Transactional
    protected void doWork() {
        try {
            log.debug( "transaction active: " + Transaction.instance().isActive() );
        } catch (Exception ignore) {}

        // some more stuff here that doesn't appear to be inside a transaction
    }
}

В разделе «Еще кое-что» я модифицировал некоторые объекты Hibernate, а затем обнаружил ошибку, из-за которой возникло исключение. Я заметил, что Исключение не вызывало откат транзакции (измененные объекты все еще были изменены в БД), поэтому я добавил запись «транзакция активна». Когда этот код выполняется, isActive () возвращает false.

Есть что-то, что я пропускаю? Почему транзакция не активна?

В случае, если это имеет значение, я использую компонент Seam внутри другого компонента, который использует аннотации RESTEasy для запуска моих вызовов методов.

1 Ответ

6 голосов
/ 27 октября 2011

Я не знаком с тем, как работает Seam, поэтому заранее извиняюсь, если этот ответ не применяется.

Я заметил, что метод @Transactional равен protected.Для меня это означает, что он вызывается другим внутренним методом.

В AOP Spring вы помечаете public методы @Transactional, которые обертываются и заменяются прокси транзакции.Когда внешний класс вызывает метод public, он вызывает прокси, который формирует транзакцию.Если внешний класс вызывает другой метод public, который не помечен @Transactional, который затем вызывает внутренний метод, то есть транзакция не будет создана, поскольку прокси-сервер вообще не вызывается.

Весной, даже если вы измените свой метод doWork() на общедоступный, возникнет та же проблема.Нет транзакции, потому что прокси-объект не вызывается.Вызовы методов, сделанные внутри класса, не вызывают вызовы прокси-объекта.

Быстрое чтение некоторой документации, кажется, указывает на то, что, подобно Spring AOP, Seam использует CGLib прокси .Вопрос в том, сможет ли он проксировать все методы - даже если они вызываются из прокси-объекта.Извините за потраченное время, если этот ответ не применяется.

...