gony-dev 님의 블로그

[Redis] Transaction 본문

DBMS

[Redis] Transaction

minarinamu 2024. 10. 15. 12:01

트랜잭션이란 나누어지지 않는 최소한의 단위로 만들어 All or Nothing 전략으로 취할 수 있도록 하는 단위이다.
트랜잭션으로 묶을 시 내부에서 하나의 로직이 실패하면 모두 취소시키며 그렇지 않으면 모두 성공시키게 된다.

Redis는 Key/Value 형태의 NoSQL이다. 인메모리로 이루어져 있기에 캐시의 형태로 많이 사용한다.

Redis Transaction

1. Redis 트랜잭션 사용방법

트랜잭션을 유지하기 위해서는 순차성을 지녀야 하며 도중에 명령어가 개입할 수 없도록 "Lock"을 걸어주어야 한다.

Redis에서는 "MULTI", "EXEC", "DISCARD", "WATCH" 명령어들을 사용한다.

각 명령어는 아래와 같은 작업을 진행한다.

  1. MULTI
    • Redis 트랜잭션을 시작하는 커맨드이다.
    • 트랜잭션 시작 시 Redis의 커맨드는 바로 실행되지 않고 queue에 쌓이게 된다.
  2. EXEC
    • 정상적으로 처리되어 queue에 쌓여있는 명령어를 일괄적으로 실행하는 명령어.
    • RDBMS의 commit과 동일한 역할을 가진다.
  3. DISCARD
    • queue에 쌓여있는 명령어를 폐기한다.
    • RDBMS의 rollback과 동일한 역할을 가진다.
  4. WATCH
    • Redis에서 Lock을 담당한다. 해당 락은 낙관적 락을 기반으로 한다.(이는 추후에 다룰 예정)
    • 해당 명령어 사용 시 UNWATCH가 되기 전까지 1번의 EXEC나 Tranaction이 아닌 다른 커맨드만 허용한다.

2. Redis Transaction Lock

Lock은 트랜잭션에서 중요한 요소로 작용한다.

만일 본인이 해당 값을 변경하고 있을 때 다른 사람이 동일한 key에 대한 값을 변경한다면 잘못된 값이 입력될 수 있기 때문이다.

이때 사용되는 것이 앞서 언급했던 "WATCH" 명령어이다!

  • WATCH를 사용하면 해당 key는 트랜잭션에서 값 변경을 1번만으로 제한할 수 있다.
  • 아래의 경우는 lock이 걸린 key에 대한 값 변경을 트랜잭샌 내에서 실패한 예시이다. 7로 값을 설정한 "KAROL"에 대해 트랜잭션에서 5로 변경을 하는 것을 감지하여 값 변경을 실패로 처리하는 것이다.
>> WATCH KAROL
"OK"
>> SET KAROL 7
"OK"
>> MULTI
"OK"
>> SET KAROL 5
"QUEUED"
>> EXEC
(nil)
  • 이를 해결하고 싶다면 "UNWATCH"를 사용하여 락을 풀어주면 Lock이 풀려 값을 변경할 수가 있다. 하지만 아래의 방법도 있다.
>> WATCH KAROL
"OK"
>> SET KAROL 22
"OK"
>> MULTI
"OK"
>> SET KAROL 11
"QUEUED"
>> EXEC
(nil)
>> MULTI
"OK"
>> SET KAORL 11
"QUEUED"
>> EXEC
1) "OK"
  • 위의 코드를 보면 트랜잭션을 2번 실행한 것을 볼 수 있는데, 2번째에는 성공을 하였다. WATCH를 사용하였을 텐데 어떻게 성공한 것일까?
    • EXEC가 호출되는 시점에서는 UNWATCH가 묵시적으로 호출되기 때문에 2번에 트랜잭션에서는 WATCH가 걸려있지 않게 된다. 그래서 이 같은 값 변경이 가능해 진다.

'DBMS' 카테고리의 다른 글

[Redis] Connection Mode-2  (0) 2024.12.08
[Redis] Connection Mode-1  (0) 2024.12.06
[Redis] Spring batch vs. Scheduler  (0) 2024.10.17