Java & Spring boot

스프링 부트 동작 순서 (트랜잭션, JDBC 커넥션, 영속성 컨텍스트와 레이어들, open-in-view)

whale3 2022. 1. 7. 22:55

https://www.youtube.com/watch?v=GAy3my6Yroc&list=PL93mKxaRDidECgjOBjPgI3Dyo8ka6Ilqm&index=46

 

부딪혀가면서 스프링 부트를 공부하고 있기 때문에 아래 내용은 틀릴 수 있다. 

틀린 부분이 발견되면 언제든지 수정할 것이고 지금은 100% 맞는 것보다 그 때 그 때 익힌 내용을 정리하고 가는게 나한테는 더 중요하다.

 

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

* 데이터의 변경이 있을때만 트랜잭션 사용한다. create, update, delete 같은 것들

 

예: 김밥 말기에는 아래와 같은 작업이 필요하다

- 김밥용 김 굽기: 이것 또한 하나의 트랜잭션

- 밥 짓기: 이것 또한 하나의 트랜잭션

- 야채 볶기: 이것 또한 하나의 트랜잭션

이 3가지 트랜잭션이 하나로 묶여서 '김밥 말기'라는 한 트랜잭션이 되기도 한다.

여러 트랜잭션을 한 트랜잭션으로 묶을 수 있고 스프링에서는 이것을 'service'라고 부름.

 

 

전통적인 스프링 부트 동작 순서

요청이 들어오면...

web.xml -> 필터 거쳐서 -> db 연결 세션 생성(JDBC 커넥션), 트랜잭션 시작, 영속성 컨텍스트 생성 -> controller 에서 요청 분기 & 각 요청에 맞는 service 호출 -> repository를 통해 select, update, delete, insert 함 -> 영속성 컨텍스트에 DB에서 select한 객체를 넣는다 (영속성 컨텍스트 1차 캐시에 데이터가 있으면 그거 들고옴. 없으면 DB에서 들고와서 1차 캐시에 넣음) -> service에서 이 (영속성 컨텍스트) 객체에서 값 바꿀 것 있으면 값 바꾸고 -> controller에 결과 알려줌 -> JDBC 커넥션 종료, 트랜잭션 종료 -> 영속성 컨텍스트에 있는 객체의 변경 사항 감지 -> 변경된 것이 있으면 DB로 flush -> 영속성 컨텍스트 종료 -> 응답 

 

포인트는 controller ----- service ------ repository 이 3가지 레이어에서 controller로 들어가기 전에 JDBC 커넥션트랜잭션영속성 컨텍스트 가 시작(생성)되며 contoller를 지난 후 JDBC 커넥션트랜잭션영속성 컨텍스트 가 끝난다는 것이다. 

 

이게 service 레이어에서 되도록 바뀌었는데 DB 부하가 줄어든다는 장점이 있지만 controller에서 select, lazy 로딩이 안된다는 단점이 있다. (service 레이어에서 영속성 컨텍스트도 없어졌으니까)

 

그래서 spring 2.0의 open-in-view(기본값 true)는 영속성 컨텍스트는 controller 레이어까지 열어두고 JDBC 커넥션, 트랜잭션만 service 레이어에서 시작 & 종료한다. 이제 controller 단에서 lazy 로딩으로 데이터를 가져올 때, 영속성 컨텍스트 1차 캐시 내의 프록시 객체가 실제 데이터가 담긴 객체가 되고(JDBC 커넥션을 잠깐 열어서 데이터 가져오고 커넥션 종료) controller 단에서 그 데이터를 유저에게 보일 수 있게 된다.

* 이 때 update, insert, delete같은 커밋해야 하는 작업은 수행할 수 없음 (service 레이어에서 이미 트랜잭션 종료했기 때문)

 

open-in-view를 false로 하면 영속성 컨텍스트도 service 단에서 종료된다. (lazy 로딩도 당연히 안된다.)

 

뭔가 알 것 같기도 하고 아리송하지만 그래도 만약 '왜 update가 안되지?' 하는 상황에서 위의 내용도 생각해 볼 수 있을 것 같다. 

반응형