새소식

반응형
Development

[Lock] 낙관적 락 & 비관적 락

  • -
반응형

데이터의 일관성 유지 - 동시에 여러 사용자가 데이터를 수정하려고 할 때 발생할 수 있는 충돌을 방지 

 

낙관적 락(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을 모두 획득하지 못하고 대기해야 한다.
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.