문제점 발생
@Transactional 어노테이션을 통해서 트랙젠션 관리를 하던 중 문제점이 발생했다.
아래 블로그에서 나와있는 내용과 같은 문제점 이었다.
https://techblog.woowahan.com/2606/
응? 이게 왜 롤백되는거지? | 우아한형제들 기술블로그
{{item.name}} 이 글은 얼마 전 에러로그 하나에 대한 호기심과 의문으로 시작해서 스프링의 트랜잭션 내에서 예외가 어떻게 처리되는지를 이해하기 위해 삽질을 해본 경험을 토대로 쓰여졌습니다.
techblog.woowahan.com
- 요약하자면 하위 트랜잭션 작업이 상위 트랜잭션 동작에 영향을 주는 것이였다.
유저에게 메세지 전송하는 시스템에서 하위 트랜잭션 작업들이 독립적으로 수행되어야 정상적으로 운영 할 수 있으므로 (하나 오류 발생하더라도 상관이 다른 메세지 전송에는 상관이 없었다. 오류는 재전송 해야 하지만)
그래서 @Transactional 설정을 이용해 문제를 해결하고자 한다.
[@Transactional Annotation 설명 글]
https://velog.io/@kdhyo/JavaTransactional-Annotation-%EC%95%8C%EA%B3%A0-%EC%93%B0%EC%9E%90-26her30h
[Java]@Transactional Annotation 알고 쓰자
초반 @Transactional 어노테이션에 대해 자세히 알아보지 않고,막연히 롤백때 사용한다고 하여 SQL C,U,D 를 할 때마다 메소드 위에 붙여서 사용하곤 하였다.하지만, 내 코드를 보신 선임께서 단지 @Tran
velog.io
- propagation 해당 옵션을 사용하면 트랜잰션 동작중 다른 트랜젝션 호출할 때의 동작을 설정 할 수 있다.
독립 적인 트랜잭션을 만들기 위해서는 2가지 옵션이 존재한다.
@Transactional(propagation = Propagation.NESTED)
@Transactional(propagation = Propagation.REQUIRES_NEW)
둘다 새로운 트랜잭션을 생성해서 작업을 해주는 옵션이다.
나는 하위 트랜잭션 작업들(메세지 전송)이 상위 트랜잭션에 영향을 안주기 위해 NESTED를 이용했다.
//상위 트랜잭션
@Transactional
public void sendLmsReservation() {
...
for (LmsCampaign lmsCampaign : lmsCampaigns) {
result += lmsSendService.sendMessage(lmsCampaign.getNo());
}
...
}
//하위 트랜잭션
@Transactional(propagation = Propagation.NESTED)
public void sendMessage(int campaignCode) {
...
lmsSendDao.insertMessage(nvRealTimeAccept);
...
}
핵심
nested는 상위 트랜잭션 안에 하위 트랜잭션을 만들어서 작업을 수행하는 것이고,
requires_new는 상위 트랜잭션에 영향을 안받는 새로운 트랜잭션을 만들어 수행하는 것이다.
주의 사항
서로 같은 클래스 내의 메소드면 롤백 적용이 되지 않는다.
외부 빈이 아닐 경우 CGLIB Proxy가 인터셉터를 하지 못하기 때문