이전 포스팅에서 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
https://thenicesj.tistory.com/491
https://thenicesj.tistory.com/622
'IT > Java' 카테고리의 다른 글
[error] Method has too many Body parameters (multiple RequestBody) (37) | 2023.11.07 |
---|---|
Openfeign 에서 fallback 동작 안할때 (56) | 2023.11.06 |
접근 제어자(public, protected, private, default) (46) | 2023.10.30 |
[eclipse] 디버깅 중 (Watch) 기능 (36) | 2023.10.27 |
Java EE / Java SE 에 대해서( feat. Java ME) (38) | 2023.10.26 |
댓글