Program Club

클래스와 메서드에서 @Transactional을 정의하는 것의 차이점은 무엇입니까

proclub 2020. 12. 29. 07:31
반응형

클래스와 메서드에서 @Transactional을 정의하는 것의 차이점은 무엇입니까


사례 1

@Transactional
public class UserServiceImpl implements UserService {

    ...................
    public void method1(){
        try{
            method2();
        }catch(Exception e){

        }
    }
    public void method2(){

    }
}

사례 2

public class UserServiceImpl implements UserService {

    ...................
    public void method1(){
        try{
            method2();
        }catch(Exception e){

        }
    }
    @Transactional
    public void method2(){

    }
}

case1에서 예외가 발생하면 롤백이 작동하지만 2의 경우 작동하지 않습니다. case1을 따를 경우 성능 문제가 있습니까?


1의 경우 @Transactional이 모든 개별 메서드에 적용됩니다. 2의 경우 @Transactional은 method1 ()이 아닌 method2 ()에만 적용됩니다.

사례 1 :-method1 () 호출-> 트랜잭션이 시작됩니다. method1 ()이 method2 ()를 호출 할 때 이미 하나가 있으므로 새로운 트랜잭션이 시작되지 않습니다.

사례 2 :-method1 () 호출-> 트랜잭션이 시작되지 않았습니다. 방법 항목 ()를 호출하면 방법 2 () NO 새로운 트랜잭션이 시작됩니다. 동일한 클래스 내에서 메서드를 호출 할 때 @Transactional이 작동하지 않기 때문입니다. 다른 클래스에서 method2 ()를 호출하면 작동합니다.

로부터 봄 참조 설명서 :

프록시 모드 (기본값)에서는 프록시를 통해 들어오는 외부 메서드 호출 만 차단됩니다. 즉, 자체 호출은 실제로 대상 개체의 다른 메서드를 호출하는 대상 개체 내의 메서드가 호출 된 메서드가 @Transactional로 표시되어 있어도 런타임에 실제 트랜잭션으로 이어지지 않음을 의미합니다. 또한 프록시는 예상되는 동작을 제공하기 위해 완전히 초기화되어야하므로 초기화 코드 (예 : @PostConstruct)에서이 기능에 의존해서는 안됩니다.


@Transactional클래스는 서비스의 각 메소드에 적용됩니다. 바로 가기입니다. 일반적으로 @Transactional(readOnly = true)모든 메소드가 저장소 계층에 액세스한다는 것을 알고있는 경우 서비스 클래스에 설정할 수 있습니다 . 그런 다음 @Transactional모델에서 변경을 수행하는 on 메서드로 동작을 재정의 할 수 있습니다 . 1)과 2) 사이의 성능 문제는 알려져 있지 않습니다.


다음 클래스가 있다고 가정하십시오.

@Transactional(readOnly = true)
public class DefaultFooService implements FooService {

  public Foo getFoo(String fooName) {
    // do something
  }

  // these settings have precedence for this method
  @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
  public void updateFoo(Foo foo) {
    // do something
  }
}

@Transactional클래스 수준 주석은 클래스의 모든 메서드에 적용됩니다.

그러나 메서드에 @Transactional(예 :) 주석이 추가되면 updateFoo(Foo foo)이는 클래스 수준에서 정의 된 트랜잭션 설정보다 우선합니다.

더 많은 정보:


여기 에서 인용

The Spring team's recommendation is that you only annotate concrete classes with the @Transactional annotation, as opposed to annotating interfaces.

Since this mechanism is based on proxies, only 'external' method calls coming in through the proxy will be intercepted. This means that 'self-invocation', i.e. a method within the target object calling some other method of the target object, won't lead to an actual transaction at runtime even if the invoked method is marked with @Transactional!

ReferenceURL : https://stackoverflow.com/questions/23132822/what-is-the-difference-between-defining-transactional-on-class-vs-method

반응형