Redis中的事务
1.Redis事务
1.1 Redis事务的使用
Redis在执行事务的时候是不会进行回滚的,而是会继续执行余下的命令。Redis只会在语法错误或者类型和命令不匹配的情况,才会发生失败,这样可以使得Redis内部保持简单且快速。
1.2 启动事务
Redis是通过multi指令来启动事务的,由于Redis是单进程单线程进行处理数据的,所以当两个客户端都发起事务时,会进入一种队列模式,此时需要看哪个客户端先发起exec完成事务的指令,就先执行他的那部分命令(两个客户端他们的指令虽然在队列里排队,但是又相对独立,各自客户端的指令都放在一起,在各自的缓冲区中),比如客户端1 发起了multi启动事务T1, 然后客户端2也发起了 multi启动事务T2,这时客户端2对k1进行删除操作,接着客户端1进行查询操作,这时如果客户端1先执行exec指令,Redis会先处理客户端1的操作,查询出k1的值,如果这时客户端2执行exec指令排在前面,会先执行客户端2的相关指令,先将k1删除了,此时客户端执行查询k1指令会报错(返回的结果是nil,表示不存在k1了)。
在这个场景中,如果客户端k1在执行multi开启事务指令之前,先执行了watch指令,相当于加了乐观锁,当发现k1被删除后会终止执行客户端1的查询k1以及后面的指令。
1.3 使用场景分析
场景1如下,启动事务,设置k1的值,会显示queued被压入队列,设置k2的值,还是会显示queued被压入队列,再执行exec之前都会这样被压入队列,直到执行exec指令时,会将被压入队列的指令都进行执行。
场景2如下:当设置了k1的值为123后,执行watch k1监听k1指令,开启事务,执行获取k1的指令,然后执行获得全部key的指令,这时不执行exec指令,让客户端2执行指令开启事务,并且设置k1的值为aaa,获取全部key的值,最后客户端2先进行执行exec指令。
此时我们可以看到在客户端2,查看k1已经被修改为aaa了,这时再执行客户端1的exec指令,我们发现客户端1返回了nil,不再执行后面的指令。
客户端1的指令:
客户端2的指令:
- 点赞
- 收藏
- 关注作者
评论(0)