트랜잭션 격리수준(isolation level)이란 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것이다.
크게 아래 4단계로 분류한다.
- READ UNCOMMITTED
- 어떤 트랜잭션의 변경내용이 COMMIT이나 ROLLBACK과 상관없이 다른 트랜잭션에서 보여진다.
- 사용되지 않는 격리수준
- READ COMMITTED
- 어떤 트랜잭션의 변경 내용이 COMMIT 되어야만 다른 트랜잭션에서 조회할 수 있다.
- Oracle DB에서 사용
- NON-REPETABLE READ 정합성 문제 발생
- 하나의 Transaction 내에서 READ를 여러 번 할 경우 결과가 다른 문제
- REPEATABLE READ
- 트랜잭션이 시작되기 전에 커밋된 내용에 대해서만 조회한다.
- 즉, 자신의 Transaction Id보다 낮은 Transaction 의 결과만 보여준다.
- 반복해서 READ 하더라도 문제가 발생하지 않는 격리 수준
- 한 트랜잭션이 너무 길어지게 되면 트랜잭션이 시작된 시점의 데이터를 일관되게 보여줘야하기 때문에 멀티버전을 관리해야한다고 한다.
- UPDATE 부정합: 한 Transaction 내에서 READ로 읽은 데이터가 UPDATE 시에는 변경되지 않는 경우
- Phantom READ: 한 Transaction 내에서 여러 번 READ를 한 경우 없던 Data가 나타나는 경우. (DELETE는 영향 없음) 다른 Transaction의 Insert에만 영향을 받음.
START TRANSACTION; -- transaction id : 1
SELECT * FROM Member WHERE name='sikyung';
START TRANSACTION; -- transaction id : 2
SELECT * FROM Price WHERE name = 'sikyung';
UPDATE Price SET name = 'psy' WHERE name = 'sikyung';
COMMIT;
UPDATE Price SET name = 'psy' WHERE name = 'sikyung'; -- 0 row(s) affected
COMMIT;
START TRANSACTION; -- transaction id : 1
SELECT * FROM Member; -- 0건 조회
START TRANSACTION; -- transaction id : 2
INSERT INTO MEMBER VALUES(1,'sikyung',28);
COMMIT;
SELECT * FROM Member; -- 여전히 0건 조회
UPDATE Member SET name = 'psy' WHERE id = 1; -- 1 row(s) affected
SELECT * FROM Member; -- 1건 조회
COMMIT;
- SERIALIZABLE
- 읽기 작업에도 공유 잠금을 설정한다.
- 공유 잠금이 설정되어 있으면 다른 트랜잭션에서 이 레코드를 변경하지 못하게 된다.
- 동시처리 등 성능이 제일 떨어지나 가장 엄격한 격리수준
실제 Spring JPA를 활용하여 위 Transaction에 대한 결과를 보고싶으면 아래 글 참조.
2024.06.21 - [Data] - Spring JPA Transactional과 Transaction Isolation Level 격리수준 실습