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

 

1. 대학교 수업진행 

 

2. 유튜브 1강

강의준비 - 영상찍기 - 업로드

 

트랜잭션 1. 강의준비

트랜잭션 2. 영상찍기    -------- 트랜잭션 1,2,3 모두 '하나의 트랜잭션'

트랜잭션 3. 업로드 

 

트랜잭션은 트랜잭션들이 모여서 하나의 트랜잭션 일수도 있고

대학교 수업진행 + 유튜브 1강 = '하나의 트랜잭션' 일수도 있다

 

여러개의 트랜잭션을 묶어서 '서비스'라고 한다.

 

 

 

정합성 문제

 

  1. 부정합이란?

트랜잭션이 시작하고 트랜잭션이 종료할때까지 select 하면 임꺽정만 나와야하는데 중간에 홍길동이 select된것이 부정합 

[트랜잭션 시작 - 임꺽정을 select -임꺽정을 select - 장보고 select - 트랜잭션 끝]

 

 

   2. PHANTOM READ 이란?

트랜잭션이 시작하고 트랜잭션이 종료할때까지 select 하면 임꺽정만 나와야하는데 중간에 결과가 안보이는 select 값

[트랜잭션 시작 - 임꺽정을 select -임꺽정을 select - 결과없음 - 트랜잭션 끝]

데이터가 보였다 안보였다 -> 정합성이 깨짐

 

 

 

부정합 과 PHANTOM READ 를 reapeatable read 이상을 사용하여 해결한다.

 

 

 

DB의 격리수준

read commit vs reapeatable read

 

간단히 말하자면 임꺽정에서 장보고로 업데이트했을때 

read commit :  A가 업데이트 commit 하면 B는 장보고로 select 

reapeatable read : A가 업데이트 commit 하면 B는 끝까지 임꺽정으로 select

 

reapeatable read는 자신의 트랜잭션 번호보다 낮은 undo 로그를 보고 select를 해서 부정합이 발생하지 않음.

 

 

 

스프링 select할때도 정합성을 위해서 @Transactional 을 붙여줘야한다. 

 

 

 

 스프링부트의 트랜잭션

 

전통적인 방법은

세션시작 시점에 JDBC 연결 시작 ,  트랜잭션 시작, 영속성 컨텍스트 시작

Controller 끝나는 시점에 JDBC,  트랜잭션, 영속성 컨텍스트 함께 종료

 

스프링 2.0 부터 바뀜 

 

[application.yml]

jpa: 
   open-in-view: true

기본전략이 open-in-view: true

true로 해야 Lazy 로딩이 가능해진다. 

 

 

브라우저가 request 요청 ▶ Controller - Service - Repository ▶ 영속성 컨텍스트 ▶ DB

 세션이 시작                             요청                                crud             DB에서 select      선수) id 1 - 이대호 - 팀 id 1

1.영속성 컨텍스트 시작                                                                       선수 - 팀 프록시       팀) id 1 -  롯데

                                                                                                               (Lazy 전략)

 

Controller 와 Service 사이에 2. JDBC 연결 시작 ,  3. 트랜잭션 시작

 

Repository 에서 select하면 DB에서 들고와 영속성 컨텍스트 1차 캐시에 저장

- Eager 전략이면 선수객체를 select했을때 팀객체를 함께 들고오지만 

- Lazy 전략이면 선수객체를 select했을때 팀객체가 아닌 가짜 팀 프록시를 들고온다

 

Repository → service에 가져와서 update나 delete..  한 후 Controller에 전달

Service가 종료할때 JDBC 연결 종료 ,  트랜잭션 종료

 

Controller에서 팀객체를 호출하면 영속성 컨텍스트는 아직 종료되지 않았기에 프록시 객체가 실제 팀객체를 변경.

DB에 접근하여 JDBC 잠깐 열어서 select 만! 가능 (트랜잭션은 종료돼서 commit같은 insert, update, delete는 불가능)

Controller에는 선수객체와 팀객체를 가짐

 

 

 

 

- 세션의 시작은 서블릿이 시작되는 시점 부터~ (세션은 영속성 컨텍스트를 포함)

- 트랜잭션의 시작은 서비스 레이어부터, JDBC 커넥션도 이 시점부터.

- 트랜잭션의 종료는 서비스 계층에서 종료, JDBC 커넥션도 이 시점 부터 종료.

- 세션은 컨트롤러 영역까지 끌고 가기 때문에 영속성이 보장되어 select가 가능해지고 lazy-loading이 가능해진다.

 

 

[application.yml]

jpa: 
   open-in-view: false 

 false 라면? 

 

Service가 종료할때 JDBC 연결 종료 ,  트랜잭션 종료, 영속성 컨텍스트 종료

Controller에서 팀 프록시를 불러오려해도 영속성 컨텍스트 종료하여 들고올 수 없음..

 

반응형
LIST

+ Recent posts