Transaction의 기본 개념
정의
데이터베이스의 상태를 변화시키기 위해서 수행하는 작업의 단위이며 더 이상 분할이 불가능한 업무처리의 단위를 의미한다.
트랜잭션의 특성(ACID)
- 원자성(Atomicity)
트랜잭션에 포함되는 모든 작업이 성공적으로 처리되지 않으면 트랜잭션에 들어있는 어떤 작업도 처리되지 않아야 한다.
- 일관성(Consistency)
트랜잭션은 트랜잭션이 시작되기 전과 트랜잭션이 종료된 이후 데이터베이스가 올바르고 일관된 상태가 유지되어야 한다.
- 독립성(Isolation)
한 트랜잭션에서 데이터베이스를 변경한 내용은 트랜잭션이 커밋될 때까지 다른 작업이나 트랜잭션과 고립되어야만 한다.
- 지속성(Durability)
커밋이 되고 나면 트랜잭션에 의해 변경된 내용은 영구적이어야 한다. 데이터베이스 시스템은 데이터베이스의 상태가 유실되지 않도록 시스템 충돌 등의 문제로부터 복구할 수 있는 방법을 갖추고 있어야 한다.
트랜잭션의 종류
- Commit
하나의 트랜잭션이 성공적으로 종료된 이후 데이터베이스가 일관성있는 상태를 유지할 때 해당 트랜잭션을 정상적으로 처리하겠다고 확정하는 명령어이다.
- RollBack
하나의 트랜잭션 처리가 비정상적으로 종료되어 트랜잭션의 원자성이 깨지 경우 트랜잭션을 처음부터 시작하거나 연산된 결과를 취소시킨다.
트랜잭션의 이상 현상
- Dirty Read
아직 커밋이 되지 않고 진행 중인 트랜잭션의 데이터를 읽는 것을 의미한다.
해당 데이터가 커밋되지 않고 롤백된다고 하면 존재하지 않은 값을 읽은 것이 된다.
- Non-Repeatable Read
한 트랜잭션 내에서 동일 쿼리가 2번 실행되는 상황에서 사이에 다른 트랜잭션이 수정/삭제를 해서 두 쿼리의 결과가 다른 경우를 의미한다.
- Phantom Read
한 트랜잭션 내에서 동일 쿼리가 2번 실행되는 경우 다른 트랜잭션의 insert로 인해 기존에 없다고 판단된 값이 나오는 경우를 의미한다.
Transaction Isolation(격리 수준)
- Read Uncommitted
- 변경 내용의 COMMIT이나 ROLLBACK 여부와 상관없이 조회 가능
- Dirty Read 발생 가능
- Read Committed
- 트랜잭션의 변경 내용이 COMMIT 되어야 다른 트랜잭션에서 조회 가능
- Non-Repeatable Read 발생 가능
- Repetable Read
- 트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회 가능
- Phantom Read 발생 가능
- Serializable
- 읽기 작업에도 잠금 진행 -> 트랜잭션이 진행 중인 행 조회 불가
- 성능 저하 발생 가능
업무 중에 트랜잭션 관련 문제가 빈번하게 발생하여 관련 내용을 정리하였다.
정리한 내용 중 이상 현상의 Phantom Read와 유사한 케이스로 인한 데이터 정합성 오류가 빈번하게 발생하였다.
예시
1. 트랜잭션 A, B 실행
2. 트랜잭션 A -> id = x인 행 insert
3. 트랜잭션 B -> id = x인 행의 존재 여부 체크(insert or update 분기)
id = x인 행 insert
4. 트랜잭션 A commit
5. 트랜잭션 B commit -> 에러
위에서 설명한 Phantom Read와 완벽하게 동일한 케이스는 아니지만 트랜잭션 내에서 조회하여 없다고 판단된 값이 발생하여 문제가 된 케이스이기 때문에 유사한 케이스로 생각된다.
해결 방안
- 격리 수준 Serializable 활용
- Oracle의 Merge Into 구문 사용
- Insert 직전의 조회로 인해 일부 개선이 가능하지만 해당 조회 역시 lock을 지니진 않기 때문에 완전한 개선이 되지 않음
- delete, insert 쿼리 동시 실행
- 데이터의 존재 여부에 대한 확인을 진행하지 않고 항상 delete, insert 진행
- 반드시 동일 트랜잭션 내에서 두 쿼리가 실행되어야 함
- 효율성이 저하될 수 있음
참고자료
https://code-lab1.tistory.com/52
https://devocean.sk.com/blog/techBoardDetail.do?ID=163799
https://devlog-wjdrbs96.tistory.com/424
https://joont92.github.io/db/트랜잭션-격리-수준-isolation-level/