Skip to Content
Suffering builds character

8. Non-repeatable read

Non-repeatable read란 같은 행을 두 번 읽었는데 값이 서로 다른 현상을 말함

원인은 다른 트랜잭션에서 그 사이에 데이터 변경 작업을 진행 후 COMMIT을 수행하였기 때문

ex)

  1. 트랜잭션 A가 고객 잔액을 조회 → 100
  2. 트랜잭션 B가 잔액을 100 → 200으로 변경하고 COMMIT
  3. A가 다시 같은 고객 잔액 조회
    → 100이 아닌 200이 조회됨

쿼리의 결과가 서로 달라지게 된 원인은 다른 트랜잭션(B)에서 A가 조회한 레코드의 값을 갱신하거나 삭제하였기 때문에 발생

현재 트랜잭션 격리 레벨이 READ COMMITTED인지 확인

sql
SELECT trx_id, trx_state, trx_started, trx_operation_state, trx_tables_in_use, trx_tables_locked, trx_isolation_level FROM INFORMATION_SCHEMA.INNODB_TRX;

or

sql
SELECT @@SESSION.transaction_isolation;

Transaction A

  1. SALES 테이블에서 상품의 개수별 총 금액 연산 후 조회
  2. SALES 테이블에서 상품별 총 금액을 합산 후 조회

Transaction B

  1. PRODUCT_ID가 1인 레코드의 QUANTITY의 개수 5개 추가 후 COMMIT 수행
수행 시점트랜잭션 AA 결과트랜잭션 BB 결과
(1) BEGIN;(2) BEGIN;
(3) SELECT PRODUCT_ID, QUANTITY * PRICE FROM SALES;
PRODUCT 1(50), PRODUCT 2(80)
트랜잭션 A가 아직 COMMIT되지 않은 상태(4) UPDATE SALES SET QUANTITY = QUANTITY + 5 WHERE PRODUCT_ID = 1;
(5) COMMIT;
(6) SELECT SUM(QUANTITY * PRICE) FROM SALES;155
COMMIT;

해결 방법

격리 레벨을 REPEATABLE READ로 격상

트랜잭션 격리 레벨을 REPEATABLE READ로 격상 후 다시 테스트해보기

sql
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Last updated on