본문 바로가기
IT/Java

@Transactional 사용시 주의 사항3 (Proxy 관련 // private 금지, 트랜잭션 분리)

by 성준하이 2023. 11. 4.
반응형

이전 포스팅에서 Transactional 에 대한 설명도 다룬적이 있고

주의사항에 대해서 다룬 글이 있다.

자세한 내용은 참고 포스팅 참고 바란다.

 

이번 포스팅에서 다룰 내용은 Transactional annotation을 선언할때 주의할 점이다.

 

1. private 로 선언된 메서드에 transactional 금지

Transactional 은 CGLIB 이 Proxy를 생성하여 호출을 하게 된다.

CGLIB이 Transactional 이 걸려있는 메서드를 잡기 위해서는 외부에서 접근이 가능해야한다.

그리하여 private 로 선언 하면 해당 메서드에 접근을 못하여 transactional이 적용이 안된다.

 

2. 동일 Bean안에서(class) 여러 트랜잭션 금지

Transactional 은 AOP 기반으로 동작을 하고 AOP는 클래스단위로 처리가 된다.

그럼 하나의 Bean에서 여러개의 Transactional 이 있다면 전부 하나의 인자로 인식을 하게 된다.

그래서 아래 참고 포스팅에 내부 호출 관련된 내용을 봐도 별도의 bean을 만들어서 2개의 클래스가 동작하는것처럼 하여 구현이 되어있다.

그래서 동일 클래스에서 여러개의 transactional 이 되어있다면 분리를 시켜야한다.

@Transactional
public void transactionalTest() {
     service.insert1();
     try {
        requiresnew();
     }catch(RuntimeException e) {
     }
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void requiresnew() {
     service.insert2();

     throw new RuntimeException("err");
}

실제로 동일 클래스 내에서 위에처럼 호출을 하며 requiresnew() 를 별도 transactional 로 묶으려고 
@Transactional(propagation = Propagation.REQUIRES_NEW)
동작을 했는데 결과는 같이 commit / rollback 이 된다.

이럴경우 하나의 transactional 로 인식이 되어 그렇고 사용하려면 두개로 아래처럼 나눠줘야한다.

private final TestService testService;
..
..

@Transactional
public void transactionalTest() {
     service.insert1();
     try {
        testService.requiresnew();
     }catch(Exception e) {
     }
}
//TestService 파일
..
..

@Transactional(propagation = Propagation.REQUIRES_NEW)
public void requiresnew() {
     service.insert2();
     throw new RuntimeException("err");

}

 


참고 포스팅

https://thenicesj.tistory.com/619

 

@Transactional annotation

spring에서 사용하는 annotation 중 하나인 이 Transactional annotation에 대해 소개하려고 한다. 사용은 메서드 상단에 설정을 해준다. 예제는 아래와 같다. @Transactional public void interal() { serviceA.transactionalTe

thenicesj.tistory.com

https://thenicesj.tistory.com/491

 

@Transactional 사용시 주의 사항1 (checked Exception)

개발을 하다가 Transactional annotation을 사용하거나 본적이 있을것이다. 해당 어노테이션은 해당 메서드 내에서 어떤 작업들이 이루어지다가 에러가 날 경우 수행했던 작업을 모두 이전으로 돌려주

thenicesj.tistory.com

https://thenicesj.tistory.com/622

 

@Transactional 사용시 주의 사항2 (내부호출 / AOP 내부호출)

이전 포스팅에서 Transactional annotation에 대해서 다뤘었다. 자세한 내용은 아래 참고 포스팅을 참고 바란다. 해당 포스팅에서 언급했었고, Spring AOP 기능에서 이슈가 있는 내부호출에 대한 내용을

thenicesj.tistory.com

 

반응형

댓글