# 에러 메시지
### Caused by: co[http://m.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException:](http://m.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException:) Lock wait timeout exceeded; try restarting transaction\
### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Cannot get a connection, general err
### Error querying database. Cause: java.sql.SQLNonTransientConnectionException: No operations allowed after connection closed.
# 원인
비즈니스 로직 초반부 특정 조건을 검증하고, 검증 실패 시 return
으로 api 실행을 중단하는 로직 존재.
트랜잭션이 시작된 후 검증을 수행했기에, 트랜잭션이 정상 종료되지 않은 상태에서 api가 종료됨.
[ 문제 java 코드 ]
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus txStatus = txManager.getTransaction(def);
...
// ex) 검증 후 return → 트랜잭션이 종료되지 않고 api 중단
if (!isValid()) {
return;
}
...
txManager.commit(txStatus);
# 해결
해당 검증 로직은 DB 접근이 필요 없으므로, 트래잭션을 시작하기 전에 수행하도록 변경. (단순 검증문 위치 변경)
[ 수정된 java 코드 ]
// 트랜잭션 시작 전 검증 수행
if (!isValid()) {
return;
}
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus txStatus = txManager.getTransaction(def);
...
txManager.commit(txStatus);
# 회고 및 추가 해결책
- 트랜잭션이 필요 없는 검증 로직은 트랜잭션 외부에서 처리.
- Spring의
@Transactional
어노테이션 사용.
(@Transactional은 프록시 기반이라 내부 메서드 호출 시 트랜잭션이 적용되지 않음) - 트랜잭션이 열린 상태에서 return할 경우, rollback 또는 commit을 명시적으로 처리.
- 트랜잭션 propagation 설정에 따라 동작이 달라질 수 있음.
'Develop > Trouble Shooting' 카테고리의 다른 글
Datagrip Data Source 연결 시, invalid fetch size 문제 해결 (0) | 2024.06.16 |
---|---|
Java 에러 - Exception in thread "main" java.util.regex.PatternSyntaxException (0) | 2023.03.20 |
Spring Boot Configuration Annotation Processor not configured (0) | 2023.01.27 |
BeanCreationException 에러 (0) | 2023.01.10 |
GitHub Actions .yml 파일 추가 후, 빌드 진행 시 발생한 에러 (0) | 2022.12.08 |