https://lordofkangs.tistory.com/358
@Entity
@SequenceGenerator(
name = "USER_PK_GENERATOR",
sequenceName = "USER_PK_SEQ",
initailValue = 1,
allocationSize = 50
)
public class User() {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator="USER_PK_GENERATOR")
private Long id;
private String name;
}
Sequence 를 사용하여 데이터베이스가 자동으로 기본키를 생성 (Oracle)
SequenceGenarator 어노테이션을 같이 쓰게 된다.
DB에 하나의 트랜잭션만 접근한다면 문제가 없지만 여러개의 트랜잭션이 동시에 접근하여 '동시성 이슈'를 만든다.
동일한 기본키가 중복되어 생성되는 것이다.
이런 문제를 해결하기 위해, DB에 접근하는 클라이언트(트랜잭션)는 넓은 범위의 기본키를 할당받는다. JPA는 이를 allocationSize라 부르고 디폴트값은 50이다
한 개의 트랜잭션이 시퀀스객체에 접근하면 50개의 기본키를 미리 생성받는다.
50개는 해당 클라이언트 전용 기본키로 다른 트랜잭션이 접근할 수 없다
이렇게 미리 기본키를 할당받으면 반복해서 DB에 접근하여 기본키를 생성할 필요가 사라지고 다른 트랜잭션과의 충돌도 방지할 수 있다.
전략 뿐만이 아니라 시퀀스 객체 생성에 관한 구체적인 설정까지 개발자가 '표시'할 수 있다.
'표시'라 말하는 이유는 개발자가 '구현'하는 것이 아니기 때문이다.
'구현'은 JPA가 한다.
개발자는 구현이 필요한 부분에 어노테이션으로 '표시'만 하면 된다.
EntityManager.persist() 가 호출 되기 전에 기본키를 가져와야 하므로 하이버네이트에서 hibernate: call next value for USER_PK_SEQ 을 실행하여 기본키를 가져옴.
그 후 EntityManager.persist()를 호출하기 때문에 IDENTITY 전략과 다르게 쿼리문을 실행하지 않음.
하지만 SEQUENCE 값을 계속 DB에서 가져와서 사용해야 하기 때문에 성능에 저하를 일으킬 수 있다 . 따라서 allocationSize 의 크기를 적당히 설정하여 성능 저하를 개선시킬 수 있다.