- 트랜잭션, Redis
- Redis Transaction
All
or Nothing
전략을 취하게 해주는 단위.Nothing
)된다. 그렇지 않으면 모두 성공(All
)queue
에 쌓인다.queue
에 쌓인 커맨드를 순차적으로 실행 (= RDBMS의 Commit)queue
에 쌓인 커맨드 삭제 (= RDBMS의 Rollback)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되지 않았음을 확인할 수 있다.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"
watch
를 key
에 명시할 경우, 트랜잭션에서 해당 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
을 해제하여 변경할 수 있음을 확인.
exec
는 unwatch
를 묵시적으로 실행한다.
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"