복붙노트

[SPRING] @Transactional이 메서드 수준에서 작동하지 않습니다.

SPRING

@Transactional이 메서드 수준에서 작동하지 않습니다.

Spring 3.2.3 @ Transactional annotation에 대한 질문이 있습니다. 내 서비스 클래스는 다음과 같습니다.

@Service @Transactional
class InventoryDisclosureBO {

@Autowired InventoryDisclosureDAO inventoryDisclosureDAO;

private static final Logger log = LoggerFactory.getLogger( InventoryDisclosureBO.class);

public void processDisclosureData(InventoryDisclosureStatus data){
  validate(data);
  persist(data);
}

@Transactional(propagation = REQUIRES_NEW)
void persist(InventoryDisclosureStatus data) {
  inventoryDisclosureDAO.setAllInvalid( data.getUnit());
  inventoryDisclosureDAO.insert( data );
}

void validate(InventoryDisclosureStatus data) {
 ...
}
}

persist () 메서드를 호출하면 모든 것이 완벽하게 작동합니다. 그러나 클래스 수준에서 @Transactional을 주석 처리하면 트랜잭션이 시작되지 않습니다. 아무도 왜 봄이 메톨 레벨에서만 @Transactional을 무시할 수 있다고 말할 수 있습니까?

해결법

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

    1.동일한 클래스에 속해 있기 때문에 processDisclosureData ()에서 persist ()를 호출 할 수 없으며 Spring에서 InventoryDisclosureBO로 만든 트랜잭션 프록시를 바이 패스합니다. @Transactional 어노테이션이 작동하도록 다른 빈에서 호출해야합니다. Spring이 InventoryDisclosureBO 빈에 대한 참조를 다른 빈에 삽입하면 트랜잭션 로직을 포함하는 InventoryDisclosureBOProxy에 대한 참조가 실제로 주입된다.

    동일한 클래스에 속해 있기 때문에 processDisclosureData ()에서 persist ()를 호출 할 수 없으며 Spring에서 InventoryDisclosureBO로 만든 트랜잭션 프록시를 바이 패스합니다. @Transactional 어노테이션이 작동하도록 다른 빈에서 호출해야합니다. Spring이 InventoryDisclosureBO 빈에 대한 참조를 다른 빈에 삽입하면 트랜잭션 로직을 포함하는 InventoryDisclosureBOProxy에 대한 참조가 실제로 주입된다.

        class Bean2 {
    
          @Autowire
          private InventoryDisclosureBO idbo;   <-- Spring will inject a proxy here
    
          public void persist(InventoryDisclosureStatus data) {
               idbo.persist(data);     <-- now it will work via proxy
          }
    ...
    
  2. ==============================

    2.이것은 스프링이 트랜잭션 프록시를 생성하는 방법과 관련됩니다.

    이것은 스프링이 트랜잭션 프록시를 생성하는 방법과 관련됩니다.

    클래스 레벨에서 @Transactional을 사용하는 경우 InventoryDisclosureBO.processDisclosureData ()를 호출하면 실제로 트랜잭션을 시작하는 Spring 프록시를 호출하고 실제 구현을 호출합니다.

    persis ()에 @Transaction 만있는 경우 InventoryDisclosureBO.processDisclosureData ()를 호출하면 Spring이 트랜잭션을 시작하지 않고 InventoryDisclosureBO.persist ()를 호출 한 것을 감지 할 수 없습니다.

    따라서 Spring은 트랜잭션 프록시를 추가 할 수 없으므로 persist에 대한 주석을 기본적으로 무시합니다.

    일반적으로 @Transactional 주석은 public 메서드에 있어야하며 호출 계층 구조가 상당히 높아야합니다 (그렇지 않으면 각 지속성이 새 트랜잭션을 생성하게됩니다)

    이 다른 질문에 대한 더 많은 정보를 찾을 수 있습니다 : 개인 메서드에 대한 메서드 인터셉터 (비공개 메서드는 같은 방식으로 동작합니다)

  3. from https://stackoverflow.com/questions/18590170/transactional-does-not-work-on-method-level by cc-by-sa and MIT license