트랜잭션 전파 속성 REQUIRES_NEW 관련 질문
- 작성자 :
- 임*희
- 작성일 :
- 2023-08-23 11:23:25
- 조회수 :
- 344
- 구분 :
- 적용지원(기술지원)
- 진행상태 :
- 완료
Q
안녕하세요 트랜잭션 관련해서 질문이 있어서 글을 남깁니다.
현재 같은 Datasource를 공유하는 트랜잭션매니저 2개를 만들어서 테스트 중입니다. 1개는 전반적인 일반 비지니스 로직에 적용되는 트랜잭션 매니저이고, 다른 1개는 API 호출시 관련 데이터를 DB에 저장하는 로직에 사용되는 트랜잭션 매니저입니다.
파일에 다음과 같이 선언 되어있습니다.
//로그 저장 하는 메소드 호출시 관리하는 트랜잭션매니저
<bean id="logTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="egov.dataSource"/>
</bean>
<tx:advice id="logTxAdvice" transaction-manager="logTxManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRES_NEW" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
... aop config 생략
//일반 트랜잭션 매니저
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="egov.dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
실행 순서는 다음과 같습니다.
1. A라는 비지니스 로직이 실행된다(A 트랜잭션매니저, 트랜잭션 전파 : REQUIRES)
2. B라는 로직(API 관련 데이터 저장)이 실행된다(B 트랜잭션매니저, 트랜잭션 전파 : REQUIRES_NEW)
제가 기대한 바로는 API 데이터 저장 메소드가 호출되면 새로운 db 커넥션을 획득해서 별도의 트랜잭션으로 관리 되는 것이었는데, 테스트를 해보니까 같은 커넥션을 공유하는것같습니다. A라는 비지니스 로직이 실패해서 예외가 발생해도 API관련 데이터 저장 로직에 영향을 주지 않기 위해서 별도로 분리하려고합니다.
제가 한 테스트 결과는, A 비지니스 로직(특정 테이블에 데이터 INSERT) 호출 하고 B라는 비지니스 로직(API 데이터 INSERT) 호출 후 B 메소드가 종료되고 COMMIT을 하면 A 로직에서 INSERT한 데이터도 COMMIT이 됩니다. 즉, REQUIRES_NEW 전파속성이 실행되지않는것같습니다.
예시)
finally {
B();
}
원인은 도저히 모르겠습니다 .. 답변 부탁드립니다.
현재 같은 Datasource를 공유하는 트랜잭션매니저 2개를 만들어서 테스트 중입니다. 1개는 전반적인 일반 비지니스 로직에 적용되는 트랜잭션 매니저이고, 다른 1개는 API 호출시 관련 데이터를 DB에 저장하는 로직에 사용되는 트랜잭션 매니저입니다.
파일에 다음과 같이 선언 되어있습니다.
//로그 저장 하는 메소드 호출시 관리하는 트랜잭션매니저
<bean id="logTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="egov.dataSource"/>
</bean>
<tx:advice id="logTxAdvice" transaction-manager="logTxManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRES_NEW" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
... aop config 생략
//일반 트랜잭션 매니저
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="egov.dataSource"/>
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
실행 순서는 다음과 같습니다.
1. A라는 비지니스 로직이 실행된다(A 트랜잭션매니저, 트랜잭션 전파 : REQUIRES)
2. B라는 로직(API 관련 데이터 저장)이 실행된다(B 트랜잭션매니저, 트랜잭션 전파 : REQUIRES_NEW)
제가 기대한 바로는 API 데이터 저장 메소드가 호출되면 새로운 db 커넥션을 획득해서 별도의 트랜잭션으로 관리 되는 것이었는데, 테스트를 해보니까 같은 커넥션을 공유하는것같습니다. A라는 비지니스 로직이 실패해서 예외가 발생해도 API관련 데이터 저장 로직에 영향을 주지 않기 위해서 별도로 분리하려고합니다.
제가 한 테스트 결과는, A 비지니스 로직(특정 테이블에 데이터 INSERT) 호출 하고 B라는 비지니스 로직(API 데이터 INSERT) 호출 후 B 메소드가 종료되고 COMMIT을 하면 A 로직에서 INSERT한 데이터도 COMMIT이 됩니다. 즉, REQUIRES_NEW 전파속성이 실행되지않는것같습니다.
예시)
finally {
B();
}
원인은 도저히 모르겠습니다 .. 답변 부탁드립니다.
환경정보
-
- OS 정보 : windows
- 표준프레임워크 버전 : spring 3.2.9
- JDK(JRE) 정보 : 1.8
- WAS 정보 : tomcat 9
- DB 정보 : tibero
- 기타 환경 정보 :
A
안녕하세요.
표준프레임워크센터입니다.
기재하신 내용으로는 답변드리기는 어려울듯 합니다.
예시로든 2개의 메소드는
각각 다른 서비스클래스에 위치해야 할듯 합니다.
각각의 메소드는 별도로 호출되면 될듯 하고
예시로든 다음 코드는 불필요할것으로 예상됩니다.
finally {
B();
}
각각의 메소드에 @Transactional 어노테이션과 함께
Propagation 옵션을 지정하면 무난히 설정이 가능할 듯 합니다.
감사합니다.
표준프레임워크센터입니다.
기재하신 내용으로는 답변드리기는 어려울듯 합니다.
예시로든 2개의 메소드는
각각 다른 서비스클래스에 위치해야 할듯 합니다.
각각의 메소드는 별도로 호출되면 될듯 하고
예시로든 다음 코드는 불필요할것으로 예상됩니다.
finally {
B();
}
각각의 메소드에 @Transactional 어노테이션과 함께
Propagation 옵션을 지정하면 무난히 설정이 가능할 듯 합니다.
감사합니다.