작성
·
798
1
안녕하세요. 실무에서 비관적 락을 사용하던 것을 낙관적 락으로 변경하고자 하는데 잘 안되는 부분이 있어서 한참을 헤매다가 질문을 올립니다.
1. 기존에 version 필드가 없던 테이블에서 새로 version 필드를 추가할 때 ddl 을 어떻게 구성해야 할까요?
alter table TABLE add version int default 1 not null;
이런식으로 default 값 1 에 not null 조건을 주어서 기존 데이터들의 버전을 1로 임의로 고정해놨는데요.
만약 기존 데이터의 마그레이션이 필요 없이 테이블을 새로 생성하는 상황 이라고 한다면 not null 이나 default 조건을 안줘도 jpa가 알아서 처음부터 insert 할때 version 1부터 잘 들어가나요?
2. 엔티티에 @Version 을 추가해서 NONE 모드의 낙관적인 락은 잘 동작하는것을 확인했는데요. 그런데 추가적인 옵션을 주고 싶어서 책에 언급된 Optimistic 를 이런식으로 조회에 추가해서 사용해 보았는데요.
@Lock(LockModeType.OPTIMISTIC)
Optional<Table> findById(Long id);
조회까지는 잘 되는데 문제는 가져온 이 엔티티에 변경이 이뤄질 때 무조건 다음과 같은 알 수 없는 에러가 발생합니다. 당연히 version 컬럼은 테이블에 잘 추가되어 있습니다. 다음은 문제가 발생할떄의 로그입니다. OPTIMISTIC 모드 이렇게 사용하는게 아닌건지..
Hibernate:
select
`version`
from
`TABLE`
where
`id` =?
2020-06-03 13:20:06.595 WARN [,,,] 1888 --- [ Test worker] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 0, SQLState: S0022
2020-06-03 13:20:06.596 ERROR [,,,] 1888 --- [ Test worker] o.h.engine.jdbc.spi.SqlExceptionHelper : Column '`version`' not found.
3. 엔티티에 @Version 을 붙이면 기본적으로 그 엔티티가 낙관적인 락에 의해 수정시에 version 정보를 비교하는 로직이 추가된다고 이해를 했습니다. 그런데 특정 쿼리에 @Lock(LockModeType.OPTIMISTIC) 을 붙여주는 것은 그 쿼리를 통해 가져온 엔티티에만 추가적인 락 로직이 들어가고 만약 @Lock 이 안붙은 또다른 쿼리가 있다고 가정하고 그 쿼리도 실제 결과는 같은 엔티티를 내려준다고 했을때 후자의 쿼리로 가져온 엔티티는 NONE 모드 락만 적용되는 것이 맞을까요?
답변 1
3
안녕하세요. 익명님
1. 네 맞습니다. 한번만 간단하게 테스트 해보시길 권장합니다.
2. 오류가 version이라는 컬럼이 없다고 하는데요?? 다시한번 확인해주세요.
3. 질문이 정확히 이해가 안되지만, 네 JPA 책 16.1.5에 설명된 것 과 같이 @Lock가 없으면 NONE모드로 적용됩니다.
추가로 락은 생각보다 고민해야 할 포인트가 많습니다. 실무에 적용하기 전에 꼭! 현재 적용해야 하는 케이스들을 모두 직접 테스트 해보시고 적용하길 권장합니다.
감사합니다.