얼마전 배치를 추가하여 운영서버에 반영하였는데 위와 같은 에러가 뜨면서 쿼리들이 Lock에 걸리기 시작했다. Lock이 걸린 세션을 Kill 한 후 killed session의 connection을 정리 하려고 하였으나 lock에 걸려 서비스에 문제가 생겨 서버를 재기동하는 상황까지 발생하였다. 원인 분석이 명확하게 되지 않아 여러가지 방법을 시도하여 보았다.
- 배치주기 변경 : 기존 5초마다 반복실행하던 배치를 6분마다 작동으로 배치주기를 변경하였다.
- Lock이 걸린 쿼리를 사용하는 배치 인덱스 생성 및 쿼리 수정 : Lock 이 걸린 쿼리를 포함하고 있는 배치내에 모든 쿼리들을 전수조사하여 실행속도가 늦거나 인덱스를 타지 않고 Full Scan을 타는 쿼리들을 수정하였다.
위 두가지 개선책을 운영에 반영하여 봤지만 여전히 배치 처리량이 많은 새벽 3시에 쿼리가 Lock이 걸렸다. jboss JDBC 내의 pool size 가 작게 잡혀있어 해당 에러가 발생하였나 알아보았으나 아니였다.
이렇게 갈피를 잡지 못하던 와중 로직을 확인해보니 트랜잭션 처리가 되어있지 않은 것이 확인되었다. 배포대상을 조회 후 UPDATE 쿼리 실행 후 트랜잭션 반환이 제대로 이루어지지 않은 것이다.
해결책은
- 필요한 곳에 트랜잭션을 선언하여 사용
- 함수 자체에 트랜잭션을 선언
// 필요한 곳에 트랜잭션을 생성하여 사용
public class A {
@Autowired
private DataSourceTransactionManager txManager;
public void B {
TransactionStatus transactionStatus = CommonUtils.getTransactionStatus(txManager);
// select - update 로직
txManager.commit(transactionStatus); // commit 처리
}
}
// 함수 자체에 트랜잭션 처리
public class A {
@Transactional
public void B {
}
}
위와 같이 2가지 방법중 택1을 하여 문제를 해결할 수 있는 것으로 확인되었고, 이후 운영에 반영 후 결과는 지켜봐야 할 것 같다.
'Back-End > DB' 카테고리의 다른 글
오라클에서 정말 많이 사용하는 GROUP BY 졸업하기 (0) | 2025.03.12 |
---|---|
오라클 MERGE INTO 구문과 INACTIVE (1) | 2024.10.18 |
인덱스 구조 및 탐색 (0) | 2024.08.05 |
캐시 탐색 메커니즘 (2) | 2024.07.30 |
데이터 저장 구조 및 I/O 메커니즘 (1) | 2024.07.29 |