| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- string
- OOP
- JDBC
- 설정세팅
- 공통규약
- 클린아키텍처
- MVC요청플로우
- SpringLegacy
- 로그백
- 전전긍긍
- 커뮤니티서버
- springsecurity
- model
- 문제선택근거
- 공통기술
- SEQUENCE
- 이벤트핸들러등록
- DDD
- 냄새라도
- TDD
- index
- 이벤트핸들러this
- JPA
- 사면초가
- Transaction
- 디스크i/o
- 단위테스트
- AOP
- MVC
- Ajax
- Today
- Total
개발이군고구마
[Spring/DB]Transaction 과 Lock (@Transactional 사용에 대한 궁금증을 시작으로) 본문
1. 상황
- Redisson 활용하여 트랜잭션 안에서 또 다른 분산락을 설정 중
- @Transactional 사용시에도 락을 얻을텐데 동시에 여러 접속자가 같은 자원을 조회할 때, 왜 락이 제대로 잡히지 않는 것일까 궁금해짐
2. 스프링의 트랜잭션
[스프링의 @Transactional]
- 프록시 패턴 (트랜잭션 추상화와 AOP)
호출될 때 요청을 가로채어 DB 커넥션을 얻고 트랜잭션 처리 시작
서비스 단에서 일일이 커넥션 풀을 얻는 로직을 작성해줄 필요는 없이 프록시 객체에서 수행함
- 트랜잭션 동기화
일관된 처리 가능 (자식 트랜잭션 실패시 부모 트랜잭션까지 전파되어 롤백되는 기능)
* DB 커넥션
- 커넥션 얻는 과정

어플리케이션 시작 시점에 커넥션 풀에 이미 필요한 만큼의 커넥션이 생성되어 있음
DB 드라이버를 통해 새로운 커넥션을 획득하는 것이 아니라, 이미 생성되어 있는 커넥션을 참조하여 사용
3. 트랜잭션의 속성
[Isolation 격리수준 - Lock]
- Default : 기본 격리 수준
- READ_UNCOMMITED : 커밋되지 않은 데이터에 대한 읽기를 허용 DIRTY READ
- READ_COMMITED : 트랜잭션이 커밋이 확정 데이터만 읽기 허용
- REPEATABLE_READ : 트랜잭션이 완료될 때까지 SELECT 문장이 사용하는 모든 데이터 Shared Lock (= 다른 사용자는 그 영역에 해당하는 데이터 수정 불가능)
- SERIALIZABLE : 데이터 일관성 및 동시성 위해 MVCC 사용하지 않음
(격리 수준이 올라갈 수록 성능의 저하가 발생할 수도 있음)
[Propogation 전파옵션]
@Transactional 이 관리하는 트랜잭션의 범위
예, 트랜잭션 동작 도중 다른 트랜잭션을 호출하는 상황에 대한 선택 (롤백)

- 전파 옵션에 따라, 부모 트랜잭션 아래 하위 트랜잭션에서 커밋/롤백 호출의 범위가 달라짐
4. 락
DB의 락은 '공유자원' 즉, 레코드 에 락을 걸음
- 낙관적 락

데이터에 락을 걸지 않고 진행함
트랜잭션의 커밋과정에서 버전을 확인하고, 같지 않으면 불일치되어 트랜잭션이 롤백됨
트랜잭션을 필요로 하지 않음
- 비관적 락

트랜잭션은 충돌이 일어날 것이다 라는 가정하에 Lock을 걸음
조회할 때에는 s-Lock을 획득 -> 수정할 때는 x-Lock을 획득함
x-Lock이 일어날 때는 자원에 대한 락이 반납될때까지 기다려야 함
[SELECT 는 트랜잭션으로 처리되는가?]
- 트랜잭션이 필요하지 않음
- 하지만 락을 걸어야 하는 경우에는 트랜잭션 처리됨
[SELECT 절이 LOCK 이 걸리는 경우]
- SELECT ... FOR UPDATE (쓰기 락, Exclusive Lock) : 트랜잭션이 데이터를 읽으면서 다른 트랜잭션이 수정하지 못하도록 함
- SELECT ... LOCK IN SHARE MODE (공유 락, Shared Lock) : 다른 트랜잭션이 데이터를 읽을 수는 있으나 수정을 못하도록 막음
5. 대표적인 락 오류들
- 블로킹

한 트랜잭션이 시작되어 락을 점유하고 있는 상태에서, 같은 자원에 대해 또 다른 트랜잭션 요청이 온 경우
Lock들의 경합이 발생하여 프로세스가 작업이 진행되지 않고 멈춘 상태를 말함
- 교착상태 (=데드락)
더티체킹 (READ UNCOMITTED) 상태에서 공유락이 맞물리면 각자가 배타락을 요구하면서 생기는 경우

1) GOD(리로스1)을 업데이트 하는 트랜잭션1이 수행된다.
2) 그 사이에 GOD_ITM(리로스2) 를 업데이트 하는 트랜잭션2가 수행된다.
! 서로의 트랜잭션은 공유 자원에 대해 아직 락을 반납하지 않았다 !
3) 트랜잭션1 은 GOD_ITM 을 위해 배타락을 요구한다.
4) 트랜잭션 2는 GOD를 업데이트 하기 위해 배타락을 요구한다.
4. JPA 트랜잭션 처리
[JPA repository]
- JPA 사용 시 기본적인 메서드 사용 시에는 내부 코드에서 Transactional이 사용
- 클래스 레벨에서 이미 @Transactional(readOnly=true)가 선언

[JPA 의 영속성 컨텍스트]
- 쿼리가 실행되는 시점

참고 문헌
- JPA
https://tech.kakaopay.com/post/jpa-transactional-bri/
JPA Transactional 잘 알고 쓰고 계신가요? | 카카오페이 기술 블로그
JPA Transactional과 그에 따른 DB 쿼리 성능과의 관계에 대해서 설명합니다.
tech.kakaopay.com
JPA 영속성 컨텍스트란?
들어가기에 앞서 JPA의 영속성 컨텍스트에 대해 공부한 내용을 정리해보고자 한다.JPA는 사용하기 쉬운 만큼 알아야 할 내용도 무궁무진하다.동작 원리를 정확하게는 아니지만 대강적으로 이해
velog.io
https://goalinnext.tistory.com/118
JPA 영속성 전이 정리 - (영속성 컨텍스트 및 엔티티 생명주기, 영속성 전이 옵션과 insertable=false, u
안녕하세요. 이번 게시글에선 JPA 영속성 전이에 대해 분석해보고특히 복합키로 구성된 DB구조에서 어떻게 영속성 전이를 처리할지 알아보겠습니다. “영속성 콘텍스트”는 무엇일까요?영속
goalinnext.tistory.com
- 스프링 트랜잭셔널
https://joojimin.tistory.com/25
Spring Transactional 어디까지 알고있니?
[Spring] @Transactional 트랜잭션이란? 2개 이상의 쿼리를 하나의 커넥션으로 묶어 DB에 전송하고, 이 과정에서 에러가 발생할 경우 자동으로 모든 과정을 원래대로 되돌려 놓는다. 하나 이상의 쿼리를
joojimin.tistory.com
https://sjh9708.tistory.com/243
[Spring Boot] 트랜잭션 범위와 전파 속성(Propagation)
트랜잭션은 작업에서 예외가 발생할 경우 Rollback 처리를, 모두 성공할 경우 Commit 처리하는 실행 단위이다.Spring에서는 트랜잭션과 관련된 기술들을 제공하며, 주로 @Transactional 어노테이
sjh9708.tistory.com
- DB 커넥션
커넥션 풀이란 (Connection Pool)
1) 커넥션 풀 (Connection Pool) (1) 커넥션 풀이란 JDBC API를 사용하여 데이터베이스와 연결하기 위해 Connection 객체를 생성하는 작업은 비용이 굉장히 많이 드는 작업 중 하나이다. Connection 객체를 생성
shuu.tistory.com
'SERVER > Spring' 카테고리의 다른 글
| [Spring Security] redis/DB로 자동로그인 구현 (0) | 2025.11.28 |
|---|---|
| DispatcherServlet의 예외 처리 과정 (4) | 2025.07.11 |
| [Spring : Design Pattern] 3. AOP와 Proxy (Self Invocation부터 시작) (0) | 2024.11.09 |
| [Spring Security] 타기기에서 자동로그인 기능 풀기 (0) | 2024.10.28 |
| Session 사용 이유와 방법 (0) | 2024.10.27 |