redis中提供了事务处理机制。事务的两个主要特点:
1. 隔离性 ,事务中的命令都会被序列化,按顺序去执行,不会被外来的请求所打断
2. 原子性 , 事务中的所有命令你可以看成是一个整体,要成功则都成功,要失败,则都失败。
开启事务的常规步骤:
第一步: multi 命令 用来开启事务。 其实此时redis会为当前的连接的redis 客户端开辟一个 队列出来,然后后续的命令就好添加到这个队列中。
第二部: 正常执行我们想要执行的命令,例如: set name 'xiaohua'
第三步: exec 命令 用来提交事务。 此时添加在队列中的所有命令就会真的一条一条去执行。
例子1 - 正常步骤注释:
当开启事务后, 每成功执行一条命令后,返回的值是 ‘queued’ , 表示入队成功。
扩展:
redis中的乐观锁 check-add-set 机制 ------------------------ watch
incr 实现模拟 例子
---------------------------------------------------------------------------------------------------------------------
multi
num1 = get num
num1 = num1 + 1
exec
如果 是当个客户运行上面的例子是没有什么问题的,如果是多个用户的话,那么就会出现并发问题。如果num1 本来是1 , 客户A 运行了上面的代码 变成了 2 ,可是 如何客户B是跟客户A 同时刻运行的,此时 num1 应该 是3 才对, 而不应该是2。 为了解决这种并发问题,redis采用了 check-add-set 这种乐观锁的机制来解决这种原子性的问题。 就是 通过 watch命令去监控一个或者多个键,如果发现它的值发生了变化,那么当前的redis所执行的事务将会取消掉,即通过multi 命令生成的队列,里面装的命令就会清空掉。监控的键是在执行了watch命令后才生效。
取消事务 ---------- discard 命令
注意: 如上图,我们可以看出,当运行 discard 后,得到的结果 不再是 queued 这种入队成功的标识了。而在它之前并在 multi之后的都是 queued 标识。 而 discard 后面设置的命令都是ok, 说明 discard 执行后, 整个事务命令队列就销毁了。
网友评论