일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- jar 소스보기
- 마이바티스 트랜잭션
- 스프링 배치 메타 테이블
- JSONArray 분할
- date_format
- 문자형을 날짜형으로
- nonblocking
- str_to_date
- JSON 분리
- JSON 분할
- multi update
- 폐기하기
- 스프링 리액티브 프로그래밍
- 마리아디비
- JSON 분해
- spring webflux
- Meta Table
- 무시하기
- 성능개선
- batchInsert
- JSONObject 분할
- git stage
- ChainedTransactionManager #분산데이터베이스 #Spring Boot #MyBatis
- 날짜형을 문자형으로
- org.json
- 스테이지에 올리기
- JobExecutionAlreadyRunningException
- spring reactive programming
- 스프링 배치 공식문서
- 스프링 웹플럭스
- Today
- Total
ebson
[Spring boot, Mybatis, ChainedTransactionManager ] 분산 데이터베이스 트랜잭션 처리하기 본문
[Spring boot, Mybatis, ChainedTransactionManager ] 분산 데이터베이스 트랜잭션 처리하기
ebson 2023. 2. 23. 16:33대형 서비스에서 데이터베이스를 여러대로 분산해 효용성을 높이고 규모를 조절하는 것은 일반적인 방법이다. 그리고 데이터베이스당 트랜잭션 처리가 이루어지는 특성상 한 기능단위에서 2개 이상 데이터 소스에 접근하고자 할 때 스프링에서 별도의 작업을 취하지 않으면, 한개의 데이터 소스로만 commit 되고 다른 데이터 소스에 대한 commit이 누락될 수 있다. 즉 A 데이터 소스와 B 데이터 소스에 대한 스프링의 트랜잭션 매니저들 중 하나만 동작한다는 것이다.
이때는 스프링에서 제공하는 ChainedTransactionManager를 적용해 A, B 데이터 소스에 대한 트랜잭션이 모두 동작하도록 할 수 있다.
위 클래스의 동작 방식은 공식 문서에 따르면, 생성자의 인자로 전달받은 트랜잭션 매니저를 순서대로 처리하고 처리 중 문제가 생기면 역순으로 롤백하는 것이다. 그러므로 이 클래스를 사용할 때에는 가장 문제가 생길 가능성이 큰 트랜잭션에 대한 트랜잭션매니저를 마지막 순서에 위치시켜야 한다. 특정 트랜잭션이 롤백되면 기본적으로 이전에 수행되었던 다른 트랜잭션들을 같이 롤백시키기 때문이다.
ChainedTxConfig.java
@Configuration
public class ChainedTxConfig {
/**
* By Using the ChainedTransactionManager, you can manage a task using multiple transactions which SEPARATELY access dataSources(which are DIFFERENT dataSources).
* It processes transaction managers in order and commit or rollback in reverse. the PlatformTransactionManager rollbacked other transactions if it encounter an Exception(failed).
* !! So, you should examine which transaction manager is most likely to fail and place it last order. !!
* ChainedTransactionManager does not guarantee that all transactions are rollbacked when one is failed.
* */
@SuppressWarnings("deprecation")
@Bean(name = "chainedTransactionManager_RollbackAll_IfAccTxMgFailed")
public PlatformTransactionManager chainedTransactionManager1(@Qualifier("mgrTransactionManager") PlatformTransactionManager mgrTransactionManager
, @Qualifier("accTransactionManager") PlatformTransactionManager accTransactionManager) {
return new ChainedTransactionManager(mgrTransactionManager, accTransactionManager);
}
@SuppressWarnings("deprecation")
@Bean(name = "chainedTransactionManager_RollbackAll_IfMgrTxMgFailed")
public PlatformTransactionManager chainedTransactionManager2(@Qualifier("mgrTransactionManager") PlatformTransactionManager mgrTransactionManager
, @Qualifier("accTransactionManager") PlatformTransactionManager accTransactionManager) {
return new ChainedTransactionManager(accTransactionManager, mgrTransactionManager);
}
}
@Transactional(value="...")
@Transactional(value = "chainedTransactionManager_RollbackAll_IfAccTxMgFailed")
public void executeTask(StepContribution contribution, ChunkContext chunkContext) throws Exception {
/***/
}
ChainedTransactionManager에 대해서 한가지 유념할 만한 것은 만약 첫번째 인자로 주어진 트랜잭션 매니저에서만 트랜잭션 오류가 발생한다면 두번째 인자로 주어진 트랜잭션 매니저는 commit을 한 채로 첫번째 인자로 주어진 트랜잭션 매니저만 rollback을 하게 될 수 있다는 것이다. 그래서 데이터 정합성이 정말 중요한 작업인 경우에는 위 클래스를 사용하기보다 아예 애초에 트랜잭션을 분리해 작성하는 것을 추천한다. 그러나 조금만 주의를 기울이면 이와 같은 경우는 예방할 수 있다고 보인다.
한편, 개발자가 의도적으로 주의를 기울일 필요 없이 위와 같은 단점을 보완하면서도 같은 용도로 사용할 수 있는 것으로 JtaTransactionManager 라는 것이 있다. ChainedTransactionManager 과 비교했을 때 공부해야할 양이 많은 것으로 보이지만 분산 데이터베이스 환경에서 트랜잭션 처리에 대해 관심이 있다면 위 클래스에 대해서 알아보는 것도 추천한다.