[Redis] 6. Redis Transaction with redis-cli

최진민·2021년 11월 30일
0

Redis

목록 보기
6/6
post-thumbnail
  • 트랜잭션, Redis
  • Redis Transaction

0. 트랜잭션과 Redis


  • 트랜잭션 (Transaction)
    • 트랜잭션 : 나누어지지 않는 최소한의 작업 단위로 만들어 All or Nothing 전략을 취하게 해주는 단위.
    • 트랜잭션 내부에서 하나의 오류가 발생할 경우 이전 작업들 모두 취소(Nothing)된다. 그렇지 않으면 모두 성공(All)
  • Redis
    • key - value의 NoSQL
    • In-Memory 구조 (특히, 캐시)
    • 컬렉션
    • RDB, AOF



1. Redis Transaction


1.1 특징

  • 트랜잭션을 유지하기 위해서는 순차성Lock(다른 작업이 실행되지 못하게 한다.)이 필요하다.
  • 기본 명령어
    • MULTI
      • Redis에서 트랜잭션을 처음 시작하는 커맨드
      • 트랜잭션을 적용하면 다른 커맨드는 queue에 쌓인다.
    • EXEC
      • queue에 쌓인 커맨드를 순차적으로 실행 (= RDBMS의 Commit)
    • DISCARD
      • queue에 쌓인 커맨드 삭제 (= RDBMS의 Rollback)
    • WATCH
      • Lock, Obtimistic Lock 기반
      • 해당 명령어를 사용하게 될 경우, UNWATCH 이전에는 EXECTransaction에 오르지 않은 커맨드허용

1.2 기본 예제

  • redis-cli를 통한 multi, exec 예제

    127.0.0.1:6379> multi # 트랜잭션 시작
    OK
    127.0.0.1:6379(TX)> set name lion # 큐에 명령어 삽입
    QUEUED
    127.0.0.1:6379(TX)> set age 10 # 큐에 명령어 삽입
    QUEUED
    127.0.0.1:6379(TX)> get name # 큐에 명령어 삽입(get 결과 포함)
    QUEUED
    127.0.0.1:6379(TX)> exec # 명령어 순차 실행 (후, 트랜잭션 종료)
    1) OK
    2) OK
    3) "lion"
    
    ###
    127.0.0.1:6379> get name
    "lion"
    127.0.0.1:6379> get age
    "10"
    • exec 이후, 정상적으로 실행되는 명령어를 확인할 수 있다.
  • Rollback (= discard) 예제

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> set name a
    QUEUED
    127.0.0.1:6379(TX)> set age 11
    QUEUED
    127.0.0.1:6379(TX)> get name
    QUEUED
    127.0.0.1:6379(TX)> discard
    OK
    • discard 명령어를 명시하여 queue에 존재하는 명령어를 일괄 삭제하고 rollback 한다.
  • 잘못된 명령어 예제

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> set name choi
    QUEUED
    127.0.0.1:6379(TX)> hset blog real min
    QUEUED
    127.0.0.1:6379(TX)> lol kk #정의되지 않은 `lol`이라는 명령어를 사용
    (error) ERR unknown command `lol`, with args beginning with: `kk`,
    127.0.0.1:6379(TX)> exec # 모든 명령어가 discard(rollback) 되었다.
    (error) EXECABORT Transaction discarded because of previous errors.
  • 잘못된 자료구조 명령어 매핑

    127.0.0.1:6379> set name choi
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> hset name choi jinmin # Strings 자료구조에 Hashes 명령어인 'hset' 사용
    QUEUED
    127.0.0.1:6379(TX)> set name jinmin
    QUEUED
    127.0.0.1:6379(TX)> exec
    1) (error) WRONGTYPE Operation against a key holding the wrong kind of value
    2) OK
    127.0.0.1:6379> get name
    "jinmin"
    • 잘못된 자료구조 명령어를 사용했을 경우에 QUEUED가 명시되긴 한다.
    • 그러나, exec의 결과로 에러가 발생한다.
    • 또한, set을 통해 진행된 트랜잭션을 종료하고 get을 통해 확인하면, rollback되지 않았음을 확인할 수 있다.
      • 이는 redis에서 성능을 위해 선택한 방식

1.3 Lock 예제

  • watch 성공 예제

    127.0.0.1:6379> watch name # 'watch'를 통해 key에 lock을 걸었다.
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> set name choi
    QUEUED
    127.0.0.1:6379(TX)> exec
    1) OK
    127.0.0.1:6379> get name
    "choi"
    • watchkey에 명시할 경우, 트랜잭션에서 해당 key한 번명령어가 가능하다.
  • watch 실패 예제

    127.0.0.1:6379> watch name # lock
    OK
    127.0.0.1:6379> set name choi # 변경
    OK
    127.0.0.1:6379> multi # 트랜잭션 시작
    OK
    127.0.0.1:6379(TX)> set name jinmin # 2차 변경
    QUEUED
    127.0.0.1:6379(TX)> exec ###
    (nil)
    • exec 명령어 사용시, watch 명령어를 사용한 key는 자체적으로 Check And Set(CAS)를 내부적으로 실행하고 check 과정에서 실패한다.
  • unwatch 예제

    127.0.0.1:6379> watch name
    OK
    127.0.0.1:6379> set name choi # 1차 set
    OK
    127.0.0.1:6379> unwatch
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> set name jinmin # 2차 set
    QUEUED
    127.0.0.1:6379(TX)> exec
    1) OK
    127.0.0.1:6379> get name
    "jinmin"
    • unwatch를 통해 key에 걸린 lock을 해제하여 변경할 수 있음을 확인.

    • execunwatch묵시적으로 실행한다.

      127.0.0.1:6379> watch name
      OK
      127.0.0.1:6379> set name choi
      OK
      127.0.0.1:6379> multi
      OK
      127.0.0.1:6379(TX)> set name jinmin
      QUEUED
      127.0.0.1:6379(TX)> exec # 묵시적으로 'unwatch' 실행
      (nil) # 2번째 'set'의 명령어 결과가 없음.
      127.0.0.1:6379> multi
      OK
      127.0.0.1:6379(TX)> set name choi
      QUEUED
      127.0.0.1:6379(TX)> exec
      1) OK # 3번째 'set'의 명령어 결과가 있음. 'unwatch' 실행 확인
      127.0.0.1:6379> get name
      "choi"
profile
열심히 해보자9999

0개의 댓글