Redis的事务处理

Redis中的事务是一组命令(multi、exec、discard、watch等)的集合。事务中的命令要么一起执行,要么都不执行,事务和命令一样是最小的执行单位。事务执行过程中,不会中断事务而去执行其他客户端的命令请求,discard命令用作取消事务,事务回滚。

命令:multi,开始事务;

命令:exec,提交事务;

127.0.0.1:6379> multi
OK
127.0.0.1:6379> zadd zset 1 a 2 b 3 c
QUEUED
127.0.0.1:6379> zrange zset 0 -1
QUEUED
127.0.0.1:6379> sadd set a b c d e f g
QUEUED
127.0.0.1:6379> smembers set
QUEUED
127.0.0.1:6379> set su hahaha
QUEUED
127.0.0.1:6379> get su
QUEUED
127.0.0.1:6379> exec
1) (integer) 3
2) 1) "a"
   2) "b"
   3) "c"
3) (integer) 7
4) 1) "g"
   2) "f"
   3) "b"
   4) "a"
   5) "d"
   6) "e"
   7) "c"
5) OK
6) "hahaha"

multi表示事务的开始,QUEUED表示命令成功放入命令队列,exec提交事务,表示事务的完成;事务的命令则被(先入先出的方式)放入了事务的命令队列中。

命令:watch key [key ...],用于在事务开始之前监视任意数量的key,当调用exec命令时,如果任意一个被监视的key被其他客户端修改,则整个事务不执行。举个简单的例子:

不使用watch命令

在命令窗口1中执行完set test a,打开命令窗口2,执行其中的命令,再返回命令窗口1,执行exec。

期望结果:先执行事务,test的值为a,再将test的值改成b。由于事务在redis中先开始,却是在命令窗口2中的命令执行完以后才结束,导致最终的test的值与期望结果不一致。

命令窗口1:

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set test a
QUEUED
127.0.0.1:6379> get test 
QUEUED
127.0.0.1:6379> exec
1) OK
2) "a"
127.0.0.1:6379> get test
"a"

命令窗口2:

127.0.0.1:6379> set test b
OK
127.0.0.1:6379> get test
"b"

使用watch命令:

在命令窗口1执行完set su 111后,打开命令窗口2,并执行其中的命令,然后再回到命令窗口1,执行exec,此时命令窗口1中事务执行失败。

命令窗口1:

127.0.0.1:6379> watch su
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set su 111
QUEUED
127.0.0.1:6379> exec
(nil)

命令窗口2:

127.0.0.1:6379> get su
"hahaha"
127.0.0.1:6379> set su ha
OK
127.0.0.1:6379> get su
"ha"

显然,在redis的数据库结构类型中,肯定保存有一个watch命令与被监控key的表,watch命令就通过监控表中这些key来保证事务的安全性(保证数据一致)。

命令:discard,取消事务

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set m qweq 
QUEUED
127.0.0.1:6379> discard
OK

Redis事务的ACID

关系型数据库中,用ACID性质来检验事务功能的安全性。Redis事务保证一致性(C)和隔离性(I),但不保证原子性(A)和持久性(D)。Redis事务和关系型数据库中的事务区别:redis不支持事务回滚机制,也就是说就算事务中某个命令出错,整个事务还是会继续执行下去,直到事务中所有命令执行完。

A (Atomicity) 原子性

单条 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行不是原子性的。

C (Consistency) 一致性

1)、入队错误:错误的命令放入事务的命令队列,服务器会拒绝执行入队过程当中出现错误的事务

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set ceshi 123
QUEUED
127.0.0.1:6379> cuowumingling
(error) ERR unknown command `cuowumingling`, with args beginning with: 
127.0.0.1:6379> get ceshi
QUEUED
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.

2)、执行错误:事务执行期间发现的错误不会影响事务的执行,但是错误的命令不会执行

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set ceshi 123
QUEUED
127.0.0.1:6379> hget ceshi a
QUEUED
127.0.0.1:6379> get ceshi
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) "123"
127.0.0.1:6379> get ceshi
"123"

3)、服务器停机:情况一:redis服务器运行在无持久化的内存模式下,重启后,数据库是空白的;情况二:redis运行在持久化模式下,服务器会根据现有的备份文件来恢复数据;以上两种情况对数据一致性都不会造成影响。

因此,redis的事务能够保证数据的一致性。

I(Isolation)隔离性

redis是单进程的,并且不会中断事务而去执行其他客户端的命令请求,因此,redis的事务保证了隔离性。

D (Durability) 持久性

redis的事务是用队列包裹起来的一系列命令,没有提供任何持久化的操作,因此,redis的事务不具有持久性。

 

 

如果有写的不对的地方,请大家多多批评指正,非常感谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值