NoSQL之Redis高级实用命令详解--事务处理

原创 2013年12月05日 10:34:11

Redis事务处理

Redis对事务的支持目前还比较简单。Redis只能保证一个client发起的事务中的命令可以连续执行,而中间不会插入其他client的命令。当一个client在一个连接中发出multi命令时,这个连接会进入一个事务上下文,该连接后续的命令不会立即执行,而是先放到一个队列中,当执行exec命令时,redis会顺序的执行队列中的所有命令。

1.multi:开启一个事务 exec执行一个事务

我们来看下面的例子:

127.0.0.1:6379> set money 100
OK

127.0.0.1:6379> get money
"100"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby money 150
QUEUED
127.0.0.1:6379> incrby money 150
QUEUED
127.0.0.1:6379> decrby money 100
QUEUED
127.0.0.1:6379> exec
1) (integer) 250
2) (integer) 400
3) (integer) 300
127.0.0.1:6379> get money
"300"

首先我设置money为100,然后用multi开启事务之后的操作就会被queued(放入队列存储),直到执行exec命令之后,队列中的命令一起被执行,money被两次+150然后-100最后结果是300.

注意:如果在multi和exec之间执行了一条错误命令,那么exec执行也不会成功。

127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.

2.discard:取消一个事务

127.0.0.1:6379> get money
"300"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set money 200
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI
127.0.0.1:6379> get money
"300"

发现事务被取消之后再执行exec,就会告诉你没有事务了。

money还是原来的300没变。

3.redis事务的缺点

127.0.0.1:6379> set name 'test'
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incr money
QUEUED
127.0.0.1:6379> incr name
QUEUED
127.0.0.1:6379> exec
1) (integer) 301
2) (error) ERR value is not an integer or out of range

发现事务并没有回滚,而是把正确的执行了,而错误的没有执行。

这个和第一种说的还不一样,第一步中说的如果你在multi和exec中间执行了一条错误的命令(语法错误),那么整个事务会失败。而如果你没有语法错误,那么就不会回滚,也就失去了事务的真正意义,这是redis对事务处理有待改进的地方。

4.乐观锁复杂事务控制

乐观锁:大多数是基于数据版本(version)的记录机制实现的。即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据表添加一个“version”字段来实现取出数据时,将此版本号一同读出,之后更新时,对此版本号+1.此时,将提交数据的版本号与数据表对应记录的当前版本号进行对比,如果提交的数据版本号大于数据库当前版本号,则予以更新,否则认为是过期数据。-------svn 的版本控制就是最好的例子

Redis的乐观锁实例:假设有一个money的key,我们开2个session来对money进行赋值操作,我们来看一下结果如何?

Session1:

127.0.0.1:6379> get money
"301"
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby money 49
QUEUED

Session2:

127.0.0.1:6379> set money 400
OK
127.0.0.1:6379> get money
"400"

Session1:

127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get money
"400"

首先我们在session1中开启了对money的监控(watch key开启对key键的监控),然后开启一个事务,把命令incrby money 49放到事务队列中,等待exec执行处理。

之后我们开启session2,在session2中我们直接set money 400,这个时候我们在session2中get一下money发现已经变成400

之后我们回到session1中再用exec去执行事务队列中得incrby money 49这条命令,发现结果是nil也就是没有成功,用get命令看一下money发现是400,而不是449.

整个过程就实现了一个乐观锁。

对watch的特别说明:

watch命令会监听给定的key,当exec的时候如果监视的key从调用watch后发生过变化,则整个事务会失败。也可以调用watch多次监听多个key,这样就可以对指定的key加乐观锁了。注意watch的key是对整个连接有效的,事务也一样。如果连接断开,监视和事务都会被自动清除。当然了exec,discard,unwatch命令都会清除连接中的所有监视。

相关文章推荐

Redis事务介绍

1 什么是Redis事务  Redis通过MULTI、EXEC、DISCARD以及WATCH命令提供事务功能。Redis的事务提供一次性、按顺序执行命令的机制,并且不会中断事务去执行其他命令。Redi...

Spring Redis 事务Multi Exec Watch

今天在测试spring Redis的时候出现这么个:org.springframework.dao.InvalidDataAccessApiUsageException: ERR EXEC witho...

07_NoSQL数据库之Redis数据库:Redis的高级应用之事务处理、持久化操作、pub_sub、虚拟内存

 事务处理 Redis对事务的支持目前还比较简单。Redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。当一个cli...

NoSQL数据库之Redis数据库管理六(Redis的高级应用之事务处理、持久化操作、pub_sub、虚拟内存)

Redis对事务的支持目前还比较简单。redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。 由于redis是单线程来处理所有client的请求的所...

Redis高级实用特性(安全性、主从复制、事务处理)

安全性 主从复制 事务处理 持久化机制 发布订阅消息 虚拟内存的使用
  • apple_5
  • apple_5
  • 2017年05月15日 06:58
  • 170

NoSQL之Redis高级实用命令详解--安全和主从复制

一、安全性 为redis设置密码:设置客户端连接后进行任何其他指定前需要实用的密码。 警告:因为redis速度非常快,所以在一台较好的服务器下,一个外部用户可以在一秒钟进行150k次的密码尝试,这意味...

redis(五) 高级应用(事务处理,持久化操作,pub_sub、虚拟内存)

高级应用之事务处理,持久化操作,pub_sub、虚拟内存。 简单的事务处理: redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。当一个cli...
  • hiwymm
  • hiwymm
  • 2017年05月13日 17:48
  • 420

Redis的高级应用-事务处理、持久化、发布与订阅消息、虚拟内存使用

三、事务处理            Redis的事务处理比较简单。只能保证client发起的事务中的命令可以连续的执行,而且不会插入其他的client命令,当一个client在连接中发出multi命令...

NoSQL之Redis高级命令详解--持久化机制

Redis的持久化机制 Redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中得数据同步到硬盘来保证持久化。 Redis目前支持两种持久化方式: 1.snapshotting(快照...

NoSQL数据库的事务处理与数据一致性

随着互联网的发展,NoSQL数据库开始流行起来。相比传统关系型数据库,NoSQL数据库可以说是为性能而生,但是在事务处理与一致性方面的能力明显不足,而这方面又是一个数据库产品不能不去面对的。好在主流N...
  • zsh2050
  • zsh2050
  • 2015年12月03日 21:14
  • 2142
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:NoSQL之Redis高级实用命令详解--事务处理
举报原因:
原因补充:

(最多只允许输入30个字)