복붙노트

[SPRING] 다른 메서드에서 호출 한 트랜잭션 메서드가 트랜잭션을 가져 오지 않습니다.

SPRING

다른 메서드에서 호출 한 트랜잭션 메서드가 트랜잭션을 가져 오지 않습니다.

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을 사용하고 있습니다. 여기서 내가 뭘 잘못하고 있니? 감사.

해결법

  1. ==============================

    1.그것은 스프링스 AOP의 한계 중 하나입니다. DAO 빈은 실제로 봄에 생성 될 때 프록시이기 때문에 동일한 클래스 내에서 메소드를 호출하면 조언 (트랜잭션)을 호출하지 않는다는 것을 의미합니다. 다른 pointcut도 마찬가지입니다.

    그것은 스프링스 AOP의 한계 중 하나입니다. DAO 빈은 실제로 봄에 생성 될 때 프록시이기 때문에 동일한 클래스 내에서 메소드를 호출하면 조언 (트랜잭션)을 호출하지 않는다는 것을 의미합니다. 다른 pointcut도 마찬가지입니다.

  2. ==============================

    2.네, 이것은 예상되는 행동입니다. @Transactional은 스프링에 객체 주위에 프록시를 생성하라고 지시합니다. 프록시는 다른 객체에서 객체에 대한 호출을 가로 챕니다. 프록시는 객체 내의 호출을 인터셉트하지 않습니다.

    네, 이것은 예상되는 행동입니다. @Transactional은 스프링에 객체 주위에 프록시를 생성하라고 지시합니다. 프록시는 다른 객체에서 객체에 대한 호출을 가로 챕니다. 프록시는 객체 내의 호출을 인터셉트하지 않습니다.

    이 기능을 사용하려면 "외부"에서 호출 된 메소드에 @Transactional을 추가하십시오.

  3. ==============================

    3.이것은 조금 늦었지만이 제한을 극복하는 방법을 추가하려는 것은 메소드 내에서 애플리케이션 컨텍스트에서 스프링 빈을 얻고 메소드를 호출한다는 것입니다. 응용 프로그램 컨텍스트에서 스프링 빈을 가져 오면 원래 빈이 아닌 프록시 빈이됩니다. 프록시 빈은 이제 원래 빈 대신에 메소드를 호출하기 때문에 트랜잭션 어드바이스가 그것에 구현 될 것이다.

    이것은 조금 늦었지만이 제한을 극복하는 방법을 추가하려는 것은 메소드 내에서 애플리케이션 컨텍스트에서 스프링 빈을 얻고 메소드를 호출한다는 것입니다. 응용 프로그램 컨텍스트에서 스프링 빈을 가져 오면 원래 빈이 아닌 프록시 빈이됩니다. 프록시 빈은 이제 원래 빈 대신에 메소드를 호출하기 때문에 트랜잭션 어드바이스가 그것에 구현 될 것이다.

  4. from https://stackoverflow.com/questions/5109343/transactional-method-called-from-another-method-doesnt-obtain-a-transaction by cc-by-sa and MIT license