Data

트랜잭션 격리 수준 / Transaction Isolation Level

jw92 2024. 7. 7. 19:51

트랜잭션 격리수준(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 격리수준 실습