[Redis] Transactions
1) Overview
Redis transactions allow a group of commands to be
executed sequentially; avoiding the problem of race conditions. It is not possible
that a request issued by another client is executed in the middle of the
execution of a Redis transaction. Additionally, Redis transactions are atomic,
meaning either all of the commands or none are processed.
2) Implementation
A transaction follows the format of:multi
<your command(s)>
exec
Any commands you enter between multi--exec are queued.
2.1) Example
127.0.0.1:6379> multi
127.0.0.1:6379> set num 10
127.0.0.1:6379> incrby num 10
127.0.0.1:6379> exec
(integer) 20
2.2) Discard Example
If you want to cancel your transaction while using the
redis-cli, you can just enter discard.
127.0.0.1:6379> multi
127.0.0.1:6379> set num 10
127.0.0.1:6379> incrby num 10
127.0.0.1:6379> discard
3) Errors inside a transaction
There are two types of error that can happen during a transaction:
OK
127.0.0.1:6379> set a 1
QUEUED
127.0.0.1:6379> set b 2
QUEUED
127.0.0.1:6379> lpop a
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get a
"1"
127.0.0.1:6379> get b
"2"
3.1) Before EXEC
A command may fail to be queued. For example, the command may be syntactically wrong (wrong # of arguments, name.etc). Starting with Redis 2.6.5, server will refuse the entire transaction if a before-exec error happens.3.2) After EXEC
A command may fail after exec is called, for example, if the key we are performing operation on is wrong. Unfortunately, there is no special way to handle this: even if some commands fails, the other commands will be executed.3.2.1) Example
127.0.0.1:6379> multiOK
127.0.0.1:6379> set a 1
QUEUED
127.0.0.1:6379> set b 2
QUEUED
127.0.0.1:6379> lpop a
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get a
"1"
127.0.0.1:6379> get b
"2"
4) Rollbacks
It may be odd that Redis does not roll back when commands fail during a transaction. But here are some good reasons for that:- Redis commands can fail only if it is called with a wrong syntax, or against keys holding the wrong data type. This means that these failures are a result of programming errors and should be detected during development.
- Redis is internally simplified and faster because it does not need the ability to roll back.
5) Check-and-set
WATCH is the command to do a check-and-set transaction. Watch are often used with multi-exec to ensure that a variable did not change since the moment we 'watched' it. If no such change occured, then we run out transaction. If there are changes, then the entire transaction aborts and EXEC returns a null response.For example:
127.0.0.1:6379> watch test1OK
127.0.0.1:6379> set test1
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> get test1
QUEUED
127.0.0.1:6379> exec
(nil)
5.1) WATCH - Solving race conditions
The code below works perfectly with a single client. However, if multiple clients try to increment the key about the same time, then there'll be a race condition - the variable, val, can be incremented multiple times before being set to mykey.val = GET mykey
val = val + 1
SET mykey $val
Thankfully, we can fix this using the WATCH method. The only difference here is WATCH, MULTI-EXEC are used.
watch mykey
val = GET mykey
val = val + 1
multi
SET $val
exec
Comments
Post a Comment