인프런 커뮤니티 질문&답변

Park Suhyuk님의 프로필 이미지
Park Suhyuk

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

기본 키 매핑

TableGenerator 의 경우 롤백이 되어도 시퀀스 값이 롤백되지 않는데 정상인가요?

작성

·

830

0


=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)

[질문 내용]
작성한 엔티티는 다음과 같습니다.
@Entity
@Getter
@Setter
@NoArgsConstructor
@TableGenerator( // 테이블 제너레이터를 사용하는 경우에는 반드시 @Id 명시되어 있어야 테이블 생성이 됩니다
name = "TABLE_GENERATOR",
table = "SEQ_TABLE",
pkColumnValue = "COL_GEN_TAB",
allocationSize = 1
)
public class TableType {
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "TABLE_GENERATOR")
private Long id;

private String name;

public TableType(String name) {
this.name = name;
}
}
 
실행 시에 의도적으로 예외를 던져서 롤백을 했지만, SEQ_TABLE 에는 시퀀스가 롤백되지 않고 1로 늘어나 있었는데 왜 그런지 궁금합니다.
 
TableType table = new TableType("테이블");
em.persist(table);
System.out.println(table);
if (table.getName().equals("테이블"))
throw new RuntimeException("오류 발생");
 
 

답변 1

1

안녕하세요. Park Suhyuk님, 공식 서포터즈 David입니다.

.
일반적으로 데이터베이스 내에서 사용되는 시퀀스의 경우 트랜잭션이 롤백하더라도 시퀀스 값을 롤백시키지 않습니다.

동시에 트랜잭션이 수행됨을 가정하면

A트랜잭션에서 이미 시퀀스를 1을 가져갔고 B트랜잭션이 이어 시퀀스 2를 가져갔습니다.

그런데 A가 롤백됨으로 이미 증가한 시퀀스를 -1 하거나 0으로 초기화한다면 정상적으로 처리된 B트랜잭션에서 부여된 시퀀스 2와 추후에 생성될 시퀀스는 중복이 생깁니다.
.
감사합니다.

Park Suhyuk님의 프로필 이미지
Park Suhyuk
질문자

답변 주셔서 감사합니다. 그리고 제가 질문을 좀 더 자세히 드렸어야 했는데 죄송합니다.
부연 설명과 함께 추가 질문이 있어 댓글 드립니다. :-) 

 

하나. 위의 테스트의 경우인 테이블을 통한 @TableGenerator 를 이용하는 경우에는 롤백이 되지 않았고요,  데이터베이스에서 제공하는 시퀀스를 사용하는 경우 @SequenceGenerator 사용 시에는 시퀀스가 롤백이 되었습니다 하여 문의를 드렸습니다. 

 

둘. 답변 내용 중에 시퀀스 중복을 얘기해 주셨는데, 시퀀스 사용 전에 allocation 과정을 통해서 사전 reserve 된 sequence 범위 내에서 사용되므로, 중복 사용은 되지 않을 것으로 예상되는데 왜 그런지 궁금합니다.

1. @SequenceGenerator를 사용하셨을 때 시퀀스가 롤백되는 코드를 전달해주실 수 있으실까요? 제가 동일하게 실험해보았는데 시퀀스가 롤백되진 않아서요. 데이터베이스는 H2 1.4.200를 사용하여 테스트했습니다.

2. 시퀀스가 롤백되었을 때 동일한 범위를 할당받는 다는 가정으로 말씀드렸습니다. 이미 커밋된 트랜잭션은 1-50의 범위에 해당하는 시퀀스를 할당받았는데 다른 트랜잭션에서 롤백이 발생하여 시퀀스가 롤백된다면 이전에 커밋된 트랜잭션과 동일한 시퀀스를 할당받을테니깐요.

Park Suhyuk님의 프로필 이미지
Park Suhyuk
질문자

보내드리는 프로젝트를 다시 코딩하면서 원인을 알게 되었습니다.  감사합니다. :-) 

일단 작성한 코드이니 https://github.com/psyoblade/inflearn-spring-jpa 공유 드립니다 ~
시퀀스와 테이블 타입의 트리거 결과 값이 차이가 나서 시퀀스는 롤백이 되었다고 착각을 했습니다. 
@SequenceGenerator 의 initialValue default 값이 1이고, @TableGenerator 의 initialValue 는 default 값이 0 이더군요, 그래서 동일하게 실행해도 Table 이 숫자가 늘어나 있고, Sequence 는 줄었다고 잘 못 보았습니다. 

두 번째의 시퀀스의 경우는 좀 더 자료를 찾아보니 시퀀스는 롤백이 안 되는게 정상적인 동작인 것이 맞는 것 같습니다.

고맙습니다.

공유해주셔서 감사합니다:)

Park Suhyuk님의 프로필 이미지
Park Suhyuk

작성한 질문수

질문하기