데이터의 일관성 유지 - 동시에 여러 사용자가 데이터를 수정하려고 할 때 발생할 수 있는 충돌을 방지
낙관적 락(Optimistic Lock)(비선점 락)
이름 그대로 트랜잭션 대부분은 충돌이 발생하지 않는다고 낙관적으로 가정하는 방법
DB의 락 기능을 사용하는 것이 아닌, 애플리케이션 계층에서 제공하는 락
트랜잭션을 커밋하기 전까지는 충돌유무를 알 수 없다
장점-성능이 좋고, 데드락 발생 가능성이 낮다
단점-충돌이 발생한 경우 이를 해결하기 위한 추가 작업 필요(재시도, 롤백..)
비관적 락(Pessimistic Lock)(선점 락)
이름 그대로 트랜잭션의 충돌이 발생한다고 가정하고 우선 락을 걸고 보는 방법
DB의 락 기능을 사용 - 대표적으로 select for update 구문
장점-데이터의 일관성을 유지하기 비교적 간편
단점-성능 저하, 데드락 발생 가능성 높음
낙관적 락-JPA
@Version 어노테이션을 사용해서 버전 관리 기능을 사용
@Entity
public class TestEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Version
private Long version;
private String test;
}
비관적 락 -JPA
@Lock(LockModeType.PESSIMISTIC_WRITE)
DeadLock 발생 내역 확인
Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction
o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1213, SQLState: 40001o.h.engine.jdbc.spi.SqlExceptionHelper : Deadlock found when trying to get lock; try restarting transactiono.h.e.j.b.internal.AbstractBatchImpl : HHH000010: On release of batch it still contained JDBC statements
## mysql
show engine innodb status;
MySQL InnoDB 락(Lock)의 종류
실제 Inno DB내부에서는 경우 여러 트랜잭션들이 경합하고 있는 상황에서 최대한의 성능을 위해서 여러 방식의 다양한 락(Lock)을 조합해서 사용하고 있다.
락의 적용 요소에 따른 분류
- Shared lock (S)
- Row-level lock
- SELECT 위한 read lock
- shared lock이 걸려있는 동안 다른 트랜잭션이 해당 row에 대해 X lock 획득(exclusive write)은 불가능하지만
S lock 획득(shared read)은 가능
- 한 row에 대해 여러 트랜잭션이 동시에 S lock을 획득 가능
- Exclusive lock (X)
- Row-level lock
- UPDATE, DELETE 위한 write lock
- exclusive lock이 걸려있으면 다른 트랜잭션이 해당 row에 대해 X, S lock을 모두 획득하지 못하고 대기해야 한다.