본문 바로가기

백/spring boot

왜 SELECT를 할때도 @Transactional을 붙이는게 좋은가?

트랜잭션 : 일이 처리되기 위한 가장 작은 단위

 

- DB 격리 수준

  1. 오라클

      READ COMMIT

A가 UPDATE 를 한 동시간대에 B가 SELECT를 하게된다면?

오라클의 경우는 변경하려고하는 데이터가 커밋이 되기 전까지는 undo영역의 데이터를 읽어옴

좌측의 A트랜잭션이 업데이트 후 커밋 직전에 B트랜잭션에서 empno=11을 조회하게 되면, 장보고가 아닌 임꺽정이 조회됩니다.

 

COMMIT 된 후 장보고를 읽어올 수 있다

이것을 READ COMMIT이라고함!

 

READ COMMIT의 정합성 문제

 

- 일어날 수 있는 문제의 경우

SELECT 를 했을때 항상 동일하게 가격이 10000원일테니, 예상 정산 결과는(SELECT 3번 한 결과물)3만원인데, COMMIT후 가격이 변해 2만원이 나타났다?!

 

위와같이 정산 서비스에 대해서 조회시 만원의 결과를 보여주다가 어느순간 커밋이후 2만원으로 결과가 보여진다면, 데이터의 정합성이 깨지는 것.(= 부정합)

이러한 현상을 PHANTOM READ(팬텀 리드: 데이터가 보였다 안보였다가 하는 현상)라 합니다.

 

이러한 팬텀 리드 현상을 해결하기 위해서는REPEATABLE READ 방식을 써야 합니다.

REPEATABLE READ 

2. MySQL

    InnoDB 스토리지 엔진

    Repeatable read 이상 방식을 사용 -> 부정합 발생하지 않음.

 

리핏테이블 리드 방식에서는 트랜젝션이 종료되지 않은 순간까지는 동일한 조회 결과가 나옴!

 

T11의 경우 T 10 , 그 전의 트랜잭션(=자기 트랜잭션보다 낮은 UNDO로그)을 SELECT하지

자기보다 늦게 시작한 T12 의 임꺽정값을 보지는 않는다.

 

그래서 이 트랜잭션을 왜 알아야하는거?

=>SELECT에도 TRANSACTION 어노테이션을 붙여야 하는 이유를 설명하기 위해서.

보통 스프링에서 CRUD에서 CUD에서만 트랜잭셔널 어노테이션을 붙이게 되는데, R에서도 트랜잭셔널 어노테이션을 붙이는게 좋음.

이유는 위에서 말했듯이 SELECT할때 정합성을 깨지 않기 위해서.

 

참고 출처 : https://employerukss.tistory.com/71

 

[메타코딩] 스프링부트 강좌 41강(블로그 프로젝트) - DB격리수준 READ COMMIT

- 트랜잭션 : 일이 처리되기 위한 가장 작은 단위 - DB 격리 수준 1. 오라클 READ COMMIT 오라클의 경우는 변경하려고하는 데이터가 커밋이 되기 전까지는 undo영역의 데이터를 읽어옵니다. 좌측의 A트

employerukss.tistory.com