Redis乐观锁控制事务

来源:互联网 发布:暗黑3装备数据库 编辑:程序博客网 时间:2024/05/20 10:23
redis对事务的支持比较简单。redis只能保证一个客户端发起的事务命令可以执行,中间不会插入其他事务。但redis集群不支持事务。因为redis是单线程的,所以做到上面这点很容易。一般redis接受到客户端的命令后会立即执行,但是如果客户端发起multi命令,redis不会立即执行,而是让当前连接进入事务上下文,把命令放到队列中,接受到exec命令后,redis会顺序执行队列中的命令。并把执行结果打包到一起返回客户端,之后就结束了事务上下文。

一、简单的事务控制

这个例子可以看到:两个set命令发出后并没有立即执行而是放到队列中,redis接受到exec命令才开始执行。
如果有两个线程同时修改了一个变量的值,如何控制事务回滚?下面看乐观锁怎么控制的?

二、乐观锁控制事务

1.什么是乐观锁?

大多是基于数据版本的记录机制。什么是数据版本?就是为数据增加一个版本标识,即为数据库表添加一个version字段,当读取数据时,把数据库版本一同读出,当做了修改后,将数据库版本+1,同修改一起提交。如果提交数据的版本号大于数据库当前版本号,提交成功。如图:


2.乐观锁实例
假设数据库中账户信息表中有一个version字段,当前值为1,账户余额为$500

这样避免了操作员B用旧数据修改表中记录的的可能。在SQL的where设置条件传入值大于已有值:where $version > version

3.在redis中怎么体现的?
redis中用watch监视key,如果key在提交前被修改,则提交不成功。如下:

当session1还没来得及对age进行修改,session2已经将age的值设为30,session1再执行的时候失败,因为session1对age加了乐观锁的缘故。
watch命令会监视key,当exec时如果监视的key从调用watch后发生过变化,则整个事务会失败。也可以调用watch多次监视多个key。

三、redis事务存在的问题
redis保证事务中的命令连续执行,但是如果其中一条命令执行失败,事务并不回滚。


为age+1的命令成功,因为name是string类型的,所以不能做加操作,命令有一个失败也不会回滚,age的值已经被修改了。

转载地址:http://blog.csdn.net/ggibenben1314/article/details/47312169
原创粉丝点击