Lewis's Tech Keep
[Database] Spring Boot에서 Isolation level은 transaction 단위로 작동하는가? 본문
Database
[Database] Spring Boot에서 Isolation level은 transaction 단위로 작동하는가?
Lewis Seo 2023. 1. 8. 01:17Spring Boot에서 Isolation level은 transaction 단위로 작동하는가?
- 결론 : Yes
- 참고링크 : https://taetaetae.github.io/2016/10/08/20161008/
- package org.springframework.transaction.annotation;

- annotation으로 설정한 순간 Isolation enum의 TransactionDefinition interface의 value를 가지게 된다.
- TransactionDefinition interface에 설정된 IsolationLevel int 값을 보고 해당 TransactionIsolationLevel을 set 해준다.

- setCurrentTransactionIsolationLevel 설정 되는 형태
- Transaction 실행 시
- AbstractReactiveTransactionManager 에서 prepareSynchronization 를 통해 setCurrentTransactionIsolationLevel 에 IsolationLevel이 설정된다.

prepareSynchronization 이 실행되는 경로
- MultiTransactionStatus registerTransactionManager 발생

다음으로
- AbstractPlatformTransactionManager getTransaction
다음으로
- AbstractPlatformTransactionManager startTransaction

다음으로
- prepareSynchronization 도착 후 isolationLevel 설정

- getTransaction → handleExistingTransaction

- handleExistingTransaction 내부
- currentIsolationLevel

commit

- DataSourceUtils prepareConnectionForTransaction

ReadOnly = true 일 때, isolationLevel을 설정하는 경우 ex. Serializable로 동작하는가?
- 결론 : No
- 내부 동작에서 suspend 후 isolationLevel을 지워버린다.
- 해당 부분은 디버거를 찍어가면서 체크
Repeatable Read 일 때 트랜잭션 도중 새로운 값이 들어올 경우 다시 읽는가?
- 결론 : No
- 참고링크 : https://www.postgresql.kr/blog/pg_phantom_read.html
- 링크2 : https://chrisjune-13837.medium.com/db-transaction-isolation-level-f21b6d1e64eb ← 영상자료 있음
- PostgresQL의 경우 Repeatable Read에서 Phantom Read 현상으로 인한 오류 발생 시 오류 return

PostgresQL에서 Repeatable Read를 적용할 경우 Phantom Read를 허용하지 않는다는데 이는 Serializable과 같은가?
- 결론 : No
- 참고 링크 : https://stackoverflow.com/questions/55516644/postgresqls-repeatable-read-allows-phantom-reads-but-its-document-says-that-it
- 링크2 : https://stackoverflow.com/questions/30668991/are-postgresql-transaction-levels-repeatable-read-and-serializable-the-same
- Repeatable Read를 적용할 경우 PostgresQL 은 MVCC (멀티 버전 컨트롤) 형식으로 운용하여 Phantom Read 현상 발생 시 오류를 발생 시키지만 이는 Phantom Read를 허용하지 않는다는 것이지 Serializable하게 만든 후 Read에 lock을 건다는 뜻이 아니다.
최종 결론
- readonly = false, isolationLevel = Serializable 로 설정한 경우에만
해당 고립 레벨에 대한 요청이 jdbc 쪽에 저장되는 것을 확인 - 해당 패턴 해결 필요 시 readonly = false, isolationLevel = Serializable 설정 필요
- serializable 해야하는 트랜잭션이 생긴다면 read에 Lock을 걸게 되는데
이를 거는 것은 데드 락 발생 가능성 및 여러 사이드 이펙트를 유발할 가능성이 생긴다.- 따라서 다른 방법을 고민해보고 마지막으로 안될 때 해당 방법으로 하는 것을 고려해야 한다.
연계 사항
- 부모의 트랜잭션이 따로 잡혀있는 경우 어떻게 대처할 것인가?
- https://jobc.tistory.com/214
- https://woodcock.tistory.com/40
- Async 어노테이션을 걸지 않고 할 경우 가능
'Database' 카테고리의 다른 글
[PostgreSQL] cached plan must not change result type 에러 (0) | 2023.01.08 |
---|---|
[Database] locking 전략과 lock에 관한 이야기 (1) | 2023.01.08 |
Comments