JPA는 영속화된 객체를 DB에 바로 insert 하지 않으므로서(쓰기 지연) 성능 이득을 제공한다고 합니다.
그런데 영속 객체는 반드시 id를 지녀야합니다.
자동생성 PK처럼 DB에 id 생성을 위임한 경우에는, 컨텍스트에 저장되는 것과는 별개로 DB에 값이 전달(flush)돼야 영속 객체에 id 값이 부여됩니다.
토막 상식(인데 정확히 답하라고하면 어버버 하게 되는)
자동 증가되는 식별자는 일반적으로 트랜잭션 외부에 존재하는 전용 lock을 지니고 있습니다.
예를들어 트랜잭션 1에서 증가시킨 식별자 값을 얻어가는 즉시 트랜잭션 종료와는 별개로 식별자 lock을 해제합니다.
insert 구문이 수행된 후에 트랜잭션이 실패하면 동일 테이블에 다음 insert 시, 식별자 값이 연속적이지 않습니다.(1개 증가가 아닌 2개 이상 증가)
하이버네이트는 이걸 어떻게 해결했는가
하이버네이트는 IDENTITY ID 전략을 지닌 객체를 persist할 때, 해당 구문을 즉시 DB로 전달합니다.
쉽게 이야기하자면 쓰기 지연이 무력화된다는 의미
결국 일반적인 케이스에서 delete나 update만 쓰기 지연 효과를 볼 수 있다는건데, delete, update를 반복적으로 쓸만한 상황이 얼마나 있을지를 생각해보면 기존 방식(MyBatis)과 비교했을 때 큰 이득이 없어보입니다.(보통 DB는 WAS와 물리적으로 가까운 거리에 있어서 네트워킹 비용이 크게 중요하지 않음)
그런데.. 검색을 해보니 persist 수행 후에 flush를 직접 수행하는 답변들이 많았음.
가장 중요한 스펙에 명백하게 반하는걸 보니, 아마도 구버전에서는 그랬던게 아닐지 추정중임
1차 캐시가 대체 어떤 이득을 주는가?
1차 캐시는 변경 감지를 위해 필수적인 요소이긴 합니다만, 굳이 캐시라는 이름을 붙일 필요가 있었나 싶을 정도로 성능과는 연관이 없어보입니다.(캐시가 주는 이득은 성능 뿐이므로..)
아래는 전제 조건입니다,
1차 캐시는 트랜잭션보다 더 큰 개념으로서 영속성 컨텍스트와 생명주기를 함께합니다.
하지만 일반적인 Spring 웹 개발에서는 영속성 컨텍스트의 수명이 트랜잭션과 동일합니다.
MySQL, SQL Server, Oracle에서 1차 캐시의 공통적인 무쓸모
Spring을 사용한 웹 개발의 경우, 일반적으로 [동일 트랜잭션] == [트랜잭션이 시작된 스택~끝 스택]
스택이 이어져있으므로, 파라미터로 객체를 전달해줄 수 있음. 즉 re select 할 일이 없음
만약 re select를 수행한다면, 최신 값을 받아야만 하거나 저세상코딩을 하고 있거나 둘중 하나임
최신 값을 받아야만 하는 경우가 존재할지?
받아온 이후에 최신 값이 바로 수정됐으면 무슨 의미인지?
굳이 찾아본 이득
1차 캐시는 마치 MySQL의 REPEATABLE READ처럼 동작합니다.(다른 트랜잭션에서 데이터를 업데이트 하든 말든 계속 같은 데이터를 돌려줌)
그런고로 MySQL에서는 불필요한 질의를 줄인다는 것을 제외하면 별다른 이득이 없습니다.
근데 위의 무쓸모를 생각하면, 현실적으로 아무런 이득이 없어보입니다.
SQL Server의 경우에는 REPEATABLE READ가 트랜잭션이 종료될 때 까지 SHARED LOCK을 잡아버리므로, 굳이 LOCK이 필요하지 않은 경우에는 성능적인 이득이 있습니다.
Oracle의 경우에는 REPEATABLE READ 자체를 지원하지 않아서, 기능상의 이득이 있겠습니다만.. 위의 공통적인 무쓸모를 생각해보면...
자동생성 PK에 대한 의문
자동생성 PK를 지니는 엔티티의 경우, 아래 세가지 내용이 서로 충돌합니다.
토막 상식(인데 정확히 답하라고하면 어버버 하게 되는)
하이버네이트는 이걸 어떻게 해결했는가
하이버네이트는 IDENTITY ID 전략을 지닌 객체를 persist할 때, 해당 구문을 즉시 DB로 전달합니다.
1차 캐시가 대체 어떤 이득을 주는가?
1차 캐시는 변경 감지를 위해 필수적인 요소이긴 합니다만, 굳이 캐시라는 이름을 붙일 필요가 있었나 싶을 정도로 성능과는 연관이 없어보입니다.(캐시가 주는 이득은 성능 뿐이므로..)
아래는 전제 조건입니다,
MySQL, SQL Server, Oracle에서 1차 캐시의 공통적인 무쓸모
굳이 찾아본 이득
1차 캐시는 마치 MySQL의 REPEATABLE READ처럼 동작합니다.(다른 트랜잭션에서 데이터를 업데이트 하든 말든 계속 같은 데이터를 돌려줌) 그런고로 MySQL에서는 불필요한 질의를 줄인다는 것을 제외하면 별다른 이득이 없습니다. 근데 위의 무쓸모를 생각하면, 현실적으로 아무런 이득이 없어보입니다.
SQL Server의 경우에는 REPEATABLE READ가 트랜잭션이 종료될 때 까지 SHARED LOCK을 잡아버리므로, 굳이 LOCK이 필요하지 않은 경우에는 성능적인 이득이 있습니다.
Oracle의 경우에는 REPEATABLE READ 자체를 지원하지 않아서, 기능상의 이득이 있겠습니다만.. 위의 공통적인 무쓸모를 생각해보면...