반응형
프로젝트 에서 고객의 요청으로 테이블 특성별로 나눠 DB를 두개의 스키마로 나눠 사용하게 되었다.
서비스에서 A스키마에 있는 테이블만 사용한다면 어노테이션으로 간단히 트랜젝션을 제어하면 되지만
당연히 두개의 스키마를 사용하게 되는 로직이 있었다.
이때는 수동으로 제어하는 다음과 같은 방법을 사용했다.
private final PlatformTransactionManager manager1;
private final PlatformTransactionManager manager2;
...
TransactionStatus Aschm = manager1.getTransaction(new DefaultTransactionDefinition());
try {
...
DAO.스키마A 사용 로직
...
manager1.commit(Aschm);
} catch(Exception e) {
manager1.rollback(Aschm);
}
...
TransactionStatus Bschm = manager2.getTransaction(new DefaultTransactionDefinition());
try {
...
DAO.스키마B 사용 로직
...
manager2.commit(Bschm);
} catch(Exception e) {
manager2.rollback(Bschm);
}
...
위의 경우는 따로 실행하는 경우이고 동시에 실행하는 경우는 다음과 같다.
private final PlatformTransactionManager manager1;
private final PlatformTransactionManager manager2;
...
TransactionStatus Aschm = manager1.getTransaction(new DefaultTransactionDefinition());
TransactionStatus Bschm = manager2.getTransaction(new DefaultTransactionDefinition());
try {
...
DAO.스키마A 사용 로직
DAO.스키마B 사용 로직
...
manager2.commit(Bschm);
manager1.commit(Aschm);
} catch(Exception e) {
manager2.rollback(Bschm);
manager1.rollback(Aschm);
}
...
※주의할점
- 트랜젝션의 종료
이때 주의할 점으로 A 트랜젝션(Aschm) 이 먼저 생성되고 그다음에 B 트랜젝션이 생성 되었는데
A가 부모 트랜젝션 B가 자식 트랜젝션이 된다.
따라서 자식 보다 부모가 먼저 커밋이나 롤백되어 버리면 자식 트랜젝션에서 발생한 작업이 불완전한 상태로 커밋이나
작업이 모두 롤백될 수 있으므로 꼭
자식 트랜젝션을 종료 시킨 후 부모를 마지막으로 종료 해야 한다.
- 커밋
위와 같이 수동제어 할때 반드시 커밋으로 생성한 트랜젝션을 종료 해야 한다.
그렇지 않으면 해당 테이블이 lock 에 걸려 다음 처럼 락에 걸리는데
lock wait timeout exceeded; try restarting transaction
이렇게 락이 걸린다면 다음 쿼리로 락을 확인할 수 도 없다
SHOW PROCESSLIST;
( 이것 때문에 DB 문제인줄 알고 몇번이나 재부팅 하였다... )
따라서 만약 트랜젝션을 수동으로 제어했는데 락이 걸렸다면 commit 을 제대로 했는지 소스를 확인하자...
'Dev > Spring boot' 카테고리의 다른 글
[spring boot/maven/logback/log4j2] spring boot 로그(log) 설정하기 (0) | 2025.03.17 |
---|---|
[spring boot] tomcat 에러 페이지 설정 ( 외장 톰캣을 사용하는 경우 ) (1) | 2024.11.18 |
[spring boot, swagger] 스웨거 cors 문제 해결 (0) | 2024.10.23 |