어플리케이션 기반 락, RDB의 락, Redis를 활용한 락으로 3가지 락을 사용한 동시성 제어를 수행해보자.

  1. JPA를 활용한 어플리케이션 레벨에서의 Optimistic Locking
  2. MySQL을 활용한 RDB에서의 Pessimistic Locking
  3. Redis를 활용한 Distributed Locking

1. JPA를 활용한 Optimistic Locking

@Version 어노테이션을 사용한 트랜잭션 충돌 체크하는 방식이고 최초 커밋만 인정하는 방식이다. 트랜잭션 커밋시 @Version 필드값을 데이터베이스의 컬럼값과 비교하고 값을 +1을 수행한다. 동일하지 않을 경우 예외발생한다. 즉 트랜잭션을 커밋하기 전까지 트랜잭션이 충돌하는지 알 수 없다.

2. MySQL을 활용한 RDB에서의 Pessimistic Locking

비관적 락은 데이터베이스 트랜잭션 락 매커니즘에 의존하는 방법이다. SQL 쿼리에 SELECT FOR UPDATE 구문을 사용하면서 해당 row에 Lock을 걸어 다른 트랜잭션이 조회하지 못하도록 한다. 낙관적 락과 다르게 version 컬럼이 필요 없으며 낙관적 락과 다르게 데이터를 수정하는 즉시 트랜잭션 충돌을 감지할 수 있다.

3. Redis를 활용한 Distributed Locking

분산 락은 여러 서버에서 동시에 접근하는 자원에 대한 액세스를 제어하는 방법으로 분산 락을 사용하면 락을 부여받기 전까지 대기하거나 포기해야 한다. 분산 락은 여러 가지 구현 방법이 있는데 Redis의 라이브러리 Redisson을 활용한 분산락을 구현할 것이다. Redis를 활용한 분산락 사용 시 클라이언트는 Redis로부터 락을 부여받아야 로직을 실행할 수 있도록해 다른 클라이언트의 접근을 방지한다. 그리고 이는 DB락을 사용하지 않으면서 데이터베이스의 충돌을 방지하고 데이터의 무결성을 유지할 수 있다.


테스트 수행 가이드

각 락 처리 방식별로 작성된 코드는 Tag를 만들어 놓았다. 테스트 수행 전 선행 되어야 하는 것들은 다음과 같다.

  1. 프로덕션 환경에서는 RDB가 필요하고 테스트 환경에서는 H2가 필요하다.
  2. 티켓을 수령받을 임의의 유저를 생성해야한다.