JPA에는
@Transactional을 이용한 트랙잭션 처리가 가능
Transactional은 Isolation level 조정이 가능
트랜잭션 격리성 관련해서는 발생할 수 있는 3가지의 문제점이 존재함
1) Dirty read
- 어떤 트랙잭션이 데이터를 수정 후 커밋하지 않았을 때, 다른 트랜잭션이 해당 데이터를 읽는다면 수정된 데이터를 읽게됨으로써 발생하는 문제
2) Non-repeatable read(특정 레코드의 데이터 무결성 관점)
- 한 트랜잭션이 데이터를 read 한 후, 다른 트랜잭션이 데이터에 접근하여 값을 변경하거나 값을 삭제하고 커밋한다면, 기존 데이터를 읽고 있던 트랜잭션이 데이터를 다시 데이터를 읽었을 때 변경된 정보를 가져오게 됨
3) Phantom read(추가/삭제된 레코드에 대한 데이터 무결성 관점)
- 한 트랜잭션이 데이터를 read 한 후, 다른 트랙잭션이 데이터를 삭제하거나 추가 했을 때, 아직 끝나지 않은 트랜잭션이 다시 데이터를 조회할 경우 추가/삭제된 데이터가 함께 조회/누락됨.
이를 해결하기 위해 4가지 방안이 존재하며, 이를 4가지 격리수준이라고 함
Transactional에서는 isolation level를 설정할 수 있음
1) Read uncommitted
- 어떤 트랙잭션에서 커밋하지 않은 데이터에, 다른 트랜잭션이 접근하는 것이 가능(읽기)
- Dirty read, Non-repeatable read, Phantom read가 발생할 수 있음
2) Read committed
- 트랜잭션이 접근하고 있을 땐, 다른 트랜잭션이 접근 불가함. 즉 커밋한 데이터만 읽을 수 있음
- Non-repeatable read, Phantom read가 발생할 수 있음
3) Repeatable read
- 트랜잭션 내에서 한번 조회한 데이터를 반복해서 조회해도 같은 데이터가 조회된다.
- Phantom read가 발생할 수 있음
4) Serializable
- 가장 엄격한 수준
- 모두가 해결할 수 있으나 성능상의 문제가 발생할 수 있음
트랙잭션이 발생할 경우 DB에는 lock이 걸리는데, select는 공유락, create, insert, delete시에는 베타적 락이 걸림
가장 이해하기 좋은 글
http://www.dbguide.net/db.db?cmd=view&boardUid=148216&boardConfigUid=9&boardIdx=138&boardStep=1
https://nesoy.github.io/articles/2019-05/Database-Transaction-isolation