Search
Duplicate

[JAVA] NoUniqueBeanDefinitionException (1)

순서
6
날짜
2022/12/22
사람
상태
Done

상황설명

테스트 코드를 작성하는 도중 트랜잭션 관련돼서 해당하는 에러가 발생하는 것을 확인했다.
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
복사
트랜잭션 롤백 참조
참조 웹사이트