미리적는 결론: 혹시 transaction이 원하는대로 작동하지 않는다면, 설정을 확인 해 보자.
egov transactional 정리
—> 현재 context-transactional에서 aop로 설정하고 있음
example패키지 안의 service, impl로 끝나는 class들,
egovframework.rte.fdl.excel.impl
패키지 안의 impl로 끝나는 class들의
모든 method들에 transaction을 만듬
해당 설정 파일 —>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="requiredTx" expression=" execution(* example..*Impl.*(..)) or
execution(* egovframework.rte.fdl.excel.impl.*Impl.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="requiredTx"/>
</aop:config>
aop로 모든 트랜잭션을 만들기 때문에
@Transactional을 붙이지 않아도 해당 클래스들에서 트랜잭션이 발생함.
문제는 현재 와일드 카드로 되어있어서 실제로 db에 안 붙는 녀석들도 트랜잭션이 생기고,
문제가 많음…
<tx:annotation-driven transaction-manager="txManager" proxy-target-class="false" />
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
일단 이런식으로 붙이면 의도한 대로 내가 붙인 곳에만 Tranasction이 생기지만,
문제는 지금 잘못 붙여진 Transactional 어노테이션이 많아서
(예를들어 class전체에 Transactional(readOnly=true)가 붙어있는데, CUD하는 METHOD들도 있어서 Exception이 터진다든지...), 차차 바꿔가야할것같다.
물론 바꾸기전에 기존 방식과 지금 방식의 차이점과 장단점도 고려해봐야할것같고...
일단 내 생각에 기존 방식의 단점은 내가 예상하지못하게 동작하는 트랜잭션들이 문제일것 같다.
실제로 내가 이 문제를 깨달은것도, db connection이 안생기는
restTemplate호출을 하는 부분에서 자꾸 트랜잭션이 발생하는 문제 때문에 알게되는것이였으니..(사실 예전에도 service에서 외부 호출만 하는데 자꾸 db connection이 생겼다 사라지는 로그가 생기길래 이건 뭐지? 하고 나중에 시간나면 알아봐야겠다 하다가 지금에야 알게되었다.)
심지어 이 aop방식은, try catch를 통한 사용자의 의도된 처리를 무시한다.
아마 해당 매핑된 클래스가 호출될때 기본(?) 트랜잭션을 만들고
거기에 method들이 만드는 트랜잭션을 전부 다 엮어서 그런것 같다.
—> 기존 트랜잭션에 합쳐지다보니
UnexpectedRollbackException 이게 발생해서 무조건 롤백되고 있다.(참고: https://techblog.woowahan.com/2606/
(유명한 '응? 이게 왜 롤백이 되는거지?'))
그래서 내가 개선된 방향이라고 생각하는 두 번째 annotation-driven 세팅은
try catch를 할 경우, 내가 원하는 대로 throw를 다시 하지 않는 한 트랜잭션을 발생시키지 않는다.
일단 왜 저 방식으로 되어있었는지 더 알아가야 할 것 같다.