node.js를 사용하면서 데드락을 경험한 일이 딱 한 번 있었다.
최근 면접에서 받은 질문으로, 복기해보려 한다.
읽기 일관성과 트랜잭션 격리 수준
배경
- node.js
- MySQL ConnectionPool
- AWS RDS
- READ 커넥션과 WRITE 커넥션의 분리
전제 조건
- [WRITE 커넥션] -> INSERT, UPDATE ... / [READ 커넥션] -> SELECT
- INSERT 쿼리는 데이터가 실제로 커밋되기 전까지 다른 트랜잭션에서 보이지 않을 수 있다.
- SELECT 쿼리는 트랜잭션 수준에 따라 최신 데이터를 읽지 못하거나, 아직 커밋되지 않은 데이터를 읽지 못할 수 있다.
- INSERT와 SELECT을 별도의 트랜잭션으로 실행하고, 두 쿼리가 다른 커넥션에서 실행된다.
- WRITE 커넥션에서 INSERT 작업이 끝난 후, 해당 데이터를 READ 커넥션에서 SELECT 쿼리로 읽을 수 없을 가능성이 존재한다.
해결 방법
- SELECT 쿼리를 READ 커넥션이 아닌, WRITE 커넥션에서 실행한다.
- WRITE 커넥션에서 트랜잭션을 묶어 INSERT 작업이 끝난 후, 해당 데이터를 SELECT 쿼리로 읽어온다.
데드락
ER_LOCK_DEADLOCK
발생 조건
- 하나의 트랜잭션이 WRITE 커넥션에서 INSERT 또는 UPDATE 쿼리를 수행하고 락을 잡는다.
- 다른 트랜잭션이 같은 데이터를 읽으려고 하거나 업데이트를 시도한다.
발생 상황
- WRITE 커넥션에서 데이터에 INSERT 혹은 UPDATE 쿼리를 실행한다.
- READ 커넥션에서 해당 데이터에 SELECT 쿼리를 실행한다.
- WRITE 커넥션에서 Commit 또는 SELECT 커넥션에서 트랜잭션 종료 작업을 시도하지만 동일한 락을 점유하여 교착상태 발생.
해결 방법
- SELECT 쿼리를 READ 커넥션이 아닌, WRITE 커넥션에서 실행한다.
AWS RDS와 MySQL ConnectionPool을 사용하면서 Reader와 Writer 커넥션간의 데드락이 발생했었다.
Writer 커넥션에 의해 수행된 INSERT, UPDATE 쿼리는 Commit이 완료된 후, Reader 커넥션이 읽을 수 있도록 Reader 커넥션쪽 DB에 데이터를 복제한다.
데이터가 복제 되기 전, Reader 쿼리를 수행하면 데이터를 읽어오지 못할 가능성이 존재했다.
위와 같은 상황에서, 커넥션끼리 트랜잭션 락을 걸고 교착상태에 빠져 하나의 커넥션을 사용하는 것으로 문제를 해결했다.
'Study > 에러 정리' 카테고리의 다른 글
Powershell) Server ping check with timestamp (0) | 2025.01.15 |
---|---|
mfc140ud.dll, afxwin1.inl Assertion 에러 (0) | 2025.01.06 |
mfc - iocp 통신 메모리 누수 (0) | 2024.12.23 |
더미클라이언트 테스트, 패킷 지연처리 (0) | 2024.09.11 |
STL std::map에서 키 값 체크 (2) | 2024.09.10 |