Подтвердить что ты не робот

@Transactional метод, вызванный из другого метода, не получает транзакции

В Spring метод, аннотированный с помощью @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. Что я здесь делаю неправильно? Спасибо.

4b9b3361

Ответ 1

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

Ответ 2

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

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

Ответ 3

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