Redis transaction mechanism

Redis transaction mechanism

 

describe

A transaction is "a complete action, either all is executed or nothing is done".

Before talking about redis transaction processing, I would like to introduce four redis instructions, namely MULTI, EXEC, DISCARD, and WATCH. These four instructions form the basis of redis transaction processing.

 

1. MULTI is used to assemble a transaction;

2. EXEC is used to execute a transaction;

3. DISCARD is used to cancel a transaction;

4. WATCH is used to monitor some keys. Once these keys are changed before the transaction is executed, the execution of the transaction is cancelled.

 

Let's look at an example:

redis> MULTI // mark the start of the transaction
OK
redis> INCR user_id //Multiple commands are queued in sequence
QUEUED
redis> INCR user_id
QUEUED
redis> INCR user_id
QUEUED
redis> PING
QUEUED
redis> EXEC //execute
1) (integer) 1
2) (integer) 2
3) (integer) 3
4) PONG

 

In the above example, we see the word QUEUED, which means that when we use MULTI to assemble a transaction, each command will be cached in the memory queue. If QUEUED appears, it means that our command was successfully inserted into the cache queue. When EXEC is executed in the future, these QUEUED commands will be assembled into a transaction for execution. Because Redis is a single-process single-line working mode, the execution of multiple commands will not be interrupted.



 

 

For the execution of the transaction, if redis enables AOF persistence, then once the transaction is successfully executed, the commands in the transaction will be written to the disk at one time through the write command. If the process of writing to the disk happens to be If there are problems such as power failure or hardware failure, then only some commands may be persisted in AOF. At this time, the AOF file will be incomplete. At this time, we can use the redis-check-aof tool to repair this problem. The problem, this tool will remove the incomplete information in the AOF file to ensure that the AOF file is complete and usable.

 

 

There are two types of errors that people often encounter when it comes to transactions:

1. Error before calling EXEC

2. Error after calling EXEC

 

 

“调用EXEC之前的错误”,有可能是由于语法有误导致的,也可能时由于内存不足导致的。只要出现某个命令无法成功写入缓冲队列的情况,redis都会进行记录,在客户端调用EXEC时,redis会拒绝执行这一事务。(这时2.6.5版本之后的策略。在2.6.5之前的版本中,redis会忽略那些入队失败的命令,只执行那些入队成功的命令)。我们来看一个这样的例子:

 

127.0.0.1:6379> multi
OK
127.0.0.1:6379> haha //一个明显错误的指令
(error) ERR unknown command 'haha'
127.0.0.1:6379> ping
QUEUED
127.0.0.1:6379> exec
//redis无情的拒绝了事务的执行,原因是“之前出现了错误”
(error) EXECABORT Transaction discarded because of previous errors.

 

 

而对于“调用EXEC之后的错误”,redis则采取了完全不同的策略,即redis不会理睬这些错误,而是继续向下执行事务中的其他命令。这是因为,对于应用层面的错误,并不是redis自身需要考虑和处理的问题,所以一个事务中如果某一条命令执行失败,并不会影响接下来的其他命令的执行。我们也来看一个例子:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 23
QUEUED
//age不是集合,所以如下是一条明显错误的指令
127.0.0.1:6379> sadd age 15 
QUEUED
127.0.0.1:6379> set age 29
QUEUED
127.0.0.1:6379> exec //执行事务时,redis不会理睬第2条指令执行错误
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) OK
127.0.0.1:6379> get age
"29" //可以看出第3条指令被成功执行了

 

 

WATCH是一个很好用的指令,它可以帮我们实现类似于“乐观锁”的效果,即CAS(check and set)

 



 

 

WATCH本身的作用是“监视key是否被改动过”,而且支持同时监视多个key,只要还没真正触发事务,WATCH都会尽职尽责的监视,一旦发现某个key被修改了,在执行EXEC时就会返回nil,表示事务无法触发。

 

127.0.0.1:6379> set age 23
OK
127.0.0.1:6379> watch age //开始监视age
OK
127.0.0.1:6379> set age 24 //在EXEC之前,age的值被修改了
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 25
QUEUED
127.0.0.1:6379> get age
QUEUED
127.0.0.1:6379> exec //触发EXEC
(nil) //事务无法被执行

 

 

 

redis 事务的执行与取消

当用户发出 EXEC 的时候,在它 MULTI 命令之后提交的所有命令都会被执行。从代码的实现来看,如果客户端监视的数据被修改,它会被标记 REDIS_DIRTY_CAS,会调用 discardTransaction() 从而取消该事务。特别的,用户开启一个事务后会提交多个命令,如果命令在入队过程中出现错误,譬如提交的命令本身不存在,参数错误和内存超额等,都会导致客户端被标记 REDIS_DIRTY_EXEC,被标记 REDIS_DIRTY_EXEC 会导致事务被取消。

 

因此总结一下:

1. REDIS_DIRTY_CAS 更改的时候会设置此标记

2. REDIS_DIRTY_EXEC 命令入队时出现错误,此标记会导致 EXEC 命令执行失败

 

 

参考:

http://www.jb51.net/article/56448.htm

http://wiki.jikexueyuan.com/project/redis/transaction-mechanism.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326482123&siteId=291194637
Recommended