Day07 JPA 심화 - 락(낙관적, 비관적)
낙관적 락, 비관적 락
- JPA에서만 통용되는 개념으로 DB에서는 낙관적락을 직접적인 지원은 없다.
1. 비관적 락
- 데이터 접근 시 락을 걸고 데이터를 읽음
- 읽기/쓰기 락을 통해서 다른 트랜젝션의 접근을 제어한다.
- 락권한을 가진 트랜잭션이 끝나기 전까지 다른 트랙잭션은 대기 상태에 남는다.
2. 낙관적 락
- 데이터 접근 시 락을 걸지 않고 데이터를 읽음
- Version을 통해서 관리를 한다.
- commit 시점에 version을 비교하여 version이 낮으면 자동 롤백
1) JPA 구현
- @Version
- 엔티티가 처음 저장될 때 버전은 0/1로 시작합니다.
- 엔티티가 수정될 때마다 버전이 자동으로 증가한다.
- 트랜잭션 충돌 시 OptimisticLockException이 발생한다.
1 2 3 4 5 6 7 8 9 10 11 12
@Entity @Builder @NoArgsConstructor @AllArgsConstructor @Setter @Getter public class Post { (...생략...) // 추가 @Version private Long version; }
- controller
1 2 3 4
@GetMapping("/modify/optimistic/{id}") public Post modifyOptimistic(@PathVariable Long id) { return postService.modifyOptimistic(id); }
- service
1 2 3 4 5 6 7 8 9 10
@SneakyThrows @Transactional public Post modifyOptimistic(Long id) { Post post = postRepository.findById(id).orElseThrow(); Thread.sleep(10_000); post.setUsername(post.getUsername() + "!"); return post; }
GET http://localhost:8080/posts/modify/optimistic/1
요청을 날리면서- SQL쿼리(DBeaver)를 통해 버전을 인위적으로 수정한다.
- 10초가 지나면 Get요청을 날린 컨트롤러에서 OptimisticLockException을 발생 시킨다.
mariadb경우 JpaSystemException / GenericJDBCException가 발생한다.
JUnitTest
- 실습코드()
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.