상황설명
•
테스트 코드를 작성하는 도중 트랜잭션 관련돼서 해당하는 에러가 발생하는 것을 확인했다.
2022-10-14 17:43:26.877 [main] DEBUG o.s.t.c.t.TestContextTransactionUtils.logBeansException(215) - Caught exception while retrieving PlatformTransactionManager for test context [DefaultTestContext@2bea5ab4 testClass = UserRoleTaskTest, testInstance = io.dktechin.prms.web.batch.task.UserRoleTaskTest@166fa74d, testMethod = testUserBan@UserRoleTaskTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@3d8314f0 testClass = UserRoleTaskTest, locations = '{classpath*:context/applicationContext*.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.PlatformTransactionManager' available: expected single matching bean but found 4: transactionManagerSlave,transactionManagerRecallSlave,transactionManager,transactionManagerRecall
Java
복사
문제점
•
tx:annotation-driven 기반 Mulitiple Transaction 설정
•
더 조사를 해봐야겠지만, 현재 파악한 문제는 해당사항으로 추측된다. 해당하는 빈에서 Transcation빈을 2개 등록을 해주고, 결국에 테스트 코드에서 어떤 빈을 등록할지 선택을 못해서 발생한다고 생각한다. >> 이 부분은 좀 더 명확하게 파악해서 수정하도록 하겠다.
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="dataSource" ref="datasource1" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="dataSource" ref="datasource2" />
</bean>
Java
복사
해결방법
•
테스트 코드에서 어떤 트랜잭션을 사용하는지 직접 지정해 줌으로써 spring이 어떤 트랜잭션 매니저를 사용할지 직접적으로 작성해 주는 것이다.
@RunWith(SpringJUnit4ClassRunner.class)
@Transactional("transactionManager")
@Slf4j
public class testCode {
Java
복사
하면서 오류를 발견하기 어려웠던 점
아래의 예시 때문에 트랜잭션이 잘 작동된다고 착각하였다. 트랜잭션이 잘 작동되는 것이 아닌, RuntimeException으로 인한 롤백이었던 것이다. 오류가 발생했는데, 왜 잘 작동되는 부분에서 좀 많이 헤매었다.
•
RuntimeException 때문에 트랜잭션을 롤백할지 결정, 딱히 지정된 규칙이 업서서 디폴트 규칙으로 롤백
•
RuntimeException 혹은 Error의 경우 rollback 하지만, checked exception은 하지 않는다.
If no custom rollback rules apply,
the transaction will roll back on {@link RuntimeException} and {@link Error}
but not on checked exceptions.
Java
복사
트랜잭션 롤백 참조
참조 웹사이트