나는 단순히 읽기(select)만 하는데 왜 transaction이 필요할까? 그런거 없어도 잘.. 되는데?
@Transactional(realOnly = false)
1. 안전한 읽기, 효율적인 읽기
우리가 따로 선언을 하지 않아도, DB 접속을 하면 우리가 별도의 설정을 안했어도 나름의 기본적인(physical) 트랜젝션을 생성한다. 이걸로 그냥 select하면 되지 왜 선언을 해야할까? 사실 그렇게 생성된 트랜젝션은 우리가 어떤 일을 할지 모르므로 변경을 위한 준비까지 해 놓는다. 즉, 우리는 10만큼만 필요한데 100만큼 준비하는 결과를 가져옴. 그래서 어플리케이션에게 우리 10만 쓸거니까 조금만 준비해~ 라고 알려줘서 성능의 향상을 가져온다.
- 변경 감지를 위한 추가적인 스냅샷을 저장하지 않아 성능 향상(메모리를 적게 사용가능)
- 커밋이나 롤백이 있지 않는 한 data pool을 들고 있는 경우가 있는데(자원을 반납하지 않음), read라고 알려주면 자원을 효율적으로 관리할 수 있음
참고: https://willseungh0.tistory.com/75
2. 데이터 구조 변경 시 안전함 보장
1번에서 말한 것과 같이 스냅샷을 저장하지 않기에 dirty checking도 일어나지 않는다. 개발자의 실수로 인한 entity set이 일어나도 저장이 되지 않으니, 그나마 안전하달까..
- 세션 플러시 모드를 MANUAL로 설정(강제로 flush를 하는게 아닌 한 디비 변화가 생기지 않음) -> 안전한 읽기
또한 오래걸리는 조회의 경우, 조회 결과를 만들면서 데이터가 수정되어 out될 때는 다른 결과를 갖게될 수도 있다. 데이터의 내용은 그렇다쳐도 혹시 데이터의 구조까지 변하게 되면 추출을 위해 몇시간을 기다렸는데 에러가 나면서 무효가 될 것이다.. 이 때 transactional을 걸어두면 transaction이 생성되는 시점의 데이터로 freeze해줘(스냅샷 생성) 일관성있는 데이터를 return받을 수 있다(데이터 구조의 변경이 있어도 영향을 받지 않아 안정적으로 데이터를 받을 수 있음).
참고) 단건의 insert/update/delete 같은 경우는 transactional이 굳이 없어도 save안에 선언된 transactional로 영속성을 유지가능, 그러나 다수의 수정이 있다면 transactional을 함수레벨에 별도로 달아서 하나의 트랜젝션으로 관리할 필요있음
'개발 > spring' 카테고리의 다른 글
[request part] file upload (0) | 2022.10.31 |
---|---|
[spring-jpa] mysql, use json(db) function in @Query (0) | 2022.10.25 |
[spring-jpa] @Transactional saveAll (0) | 2022.08.03 |
[spring-jpa] stream vs list (0) | 2022.08.01 |
[spring-jpa] composite key obtains null after save (0) | 2022.07.25 |