스프링부트의 트랜잭션 & JPA OSIV 전략

김형민·2021년 10월 18일
0
post-thumbnail

전통적인 스프링의 트랜잭션방식


1. 톰캣 시작 - 서버 작동
2. web.xml
3. context.xml (db연결 테스트)

ex) 홍길동이 장보고에게 1만원을 송금해달라는 요청을 보냄
현재 홍길동 잔액 10000 / 장보고 잔액 50000

web.xml을 지날때 데이터 베이스 연결 세션이 만들어진다.

  • 컨트롤러로 요청이 들어오고 요청에 맞는 서비스 호출
  • jdbc 커넥션이 됨(DB crud 기능 사용준비가 됨)
  • 트랜잭션 시작됨
  • ( service 시작 ) DB의 보낸사람, 받는사람 정보에 접근(SELECT)
  • 두개의 데이터를 영속성 컨텍스트에 객체화 시킨다
  • 서비스에서 홍길동과, 장보고의 정보를 가져옴
  • 홍길동의 잔액0원 장보고 잔액 60000원으로 변경시킴
  • 아직 영속성 컨텍스트의 정보만 바뀐 것
  • ( service 종료 ) 트랜잭션 종료 & 영속성 컨텍스트 닫힘(영속화된 객체 변경 감지)
  • 영속성 컨텍스트 값 변경사항이 DB에 commit(flush)
  • DB연결 세션 종료
  • 컨트롤러로 복귀
  • 데이터를 JSON 형태 응답값으로 보내줌

DB에서 업데이트할 데이터 영속성 컨테이너로 가져오고 서비스에서 업데이트 트랜잭션이 끝나면 바꾼 데이터 DB로 영속화된 객체 변경 감지 flush

JPA OSIV 전략

아래 DB에서 이대호의 정보를 EAGER 전략으로 요청한다고 가정해보자

  • 컨트롤러

  • 서비스(트랜잭션 & JDBC연결)

  • SELECT

  • 영속성 컨텍스트에(확인) 아무것도 없음

  • ( service 시작 ) DB에게 정보 요청

  • 이대호 데이터를 영속화

  • 이대호는 TeamId라는 foreign key가 있음(manyToOne) + EAGER전략으로 팀 정보까지 영속화

    LAZY일 경우 팀 정보 프록시 객체(빈 객체)를 들고옴

  • 이 두개의 정보를 서비스가 가져옴

  • ( service 종료 )그러나 이대호 선수 정보만 리턴함

  • 컨트롤러에 전달(JDBC 트랜잭션 종료 BUT 영속성 컨텍스트 종료X)

  • 팀 정보도 요청

  • 영속성 컨텍스트에 팀 프록시 객체 호출

  • JDBC 커넥션을 다시 연다

  • DB에서 정보를 가져오고 프록시 객체에서 실제 정보로 바뀜

  • 커넥션 닫음

  • 클라이언트에 응답

서비스 시작과 종료 시점에 트랜잭션 & JDBC커넥션이 시작하고 종료된다. 그러나 영속성 컨택스트의 종료가 컨트롤러에서 살아있다. 그러므로 새로운 정보를 다시 요청할 수 있음

yml 파일의 open-in-view : true로 설정하면 사용가능

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

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

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

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

참고 https://www.youtube.com/watch?v=y4a0X7dS2q8

profile
항해 중인 개발자

0개의 댓글