Метод @Transactional, вызванный из другого метода, не получает транзакцию - PullRequest
22 голосов
/ 24 февраля 2011

Весной метод, отмеченный @Transactional, получит новую транзакцию, если ее еще нет, но я заметил, что транзакционный метод не получает транзакцию, если он вызывается из нетранзакционной,Вот код.

@Component
public class FooDao {
    private EntityManager entityManager;

    @PersistenceContext
    protected void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Transactional
    public Object save(Object bean) {
        return this.entityManager.merge(bean);
    }

    public Object saveWrap(Object bean) {
        return save(bean);
    }
}

@Component
public class FooService {
    private FooDao fooDao;

    public void save(Object bean) {
        this.fooDao.saveWrap(bean); // doesn't work.
        this.fooDao.save(bean); // works
    }
}

saveWrap() - это обычный метод, который вызывает save(), который является транзакционным, но saveWrap() не сохранит никаких изменений.

Я использую Spring 3 и Hibernate 3. Что я здесь не так делаю?Благодаря.

Ответы [ 3 ]

37 голосов
/ 24 февраля 2011

Это одно из ограничений Спрингс АОП.Поскольку бин dao на самом деле является прокси, когда он создается Spring, это означает, что вызов метода из того же класса не вызовет рекомендацию (которая является транзакцией).То же самое касается любого другого pointcut

12 голосов
/ 24 февраля 2011

Да, это ожидаемое поведение. @Transactional говорит пружине создать прокси вокруг объекта. Прокси перехватывает вызовы объекта от других объектов. Прокси не перехватывает звонки внутри объекта.

Если вы хотите, чтобы это работало, добавьте @Transactional к методу, который вызывается извне.

2 голосов
/ 27 января 2016

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

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