码迷,mamicode.com
首页 > 其他好文 > 详细

redis事务

时间:2018-01-15 22:27:17      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:执行   连续   简化   修改   blog   过期   检查   不执行   读取   

  1、redis是单线程处理所有client的请求,所以redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他client的命令。

  2、在一个redis事务中,redis要么执行其中的所有命令,要不都不执行。因此,redis事务能够保证原子性

 

  命令:

  1、multi:用于标记事务块的开始。redis会将后续的命令逐个放入队列中,然后才能使用exec命令原子化的执行命令序列。

  2、exec:在一个事务中执行所有先前放入队列的命令,然后恢复正常连接状态。

      当使用watch命令时,只有当受监控的键没有被修改时,exec命令才会执行事务中的命令这种命令利用了验证再设置(cas)的机制

  3、discard:清除所有先前在一个事务中放入队列的命令,然后恢复正常连接状态,如果使用了watch命令,那么discard命令就会将当前连接监控的所有键取消监控

  4、watch:当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的。

  5、unwatch:清楚所有先前为一个事务监控的键,如果调用了exec或discard命令,那么就不需要手动调用unwatch命令

 

  事务内部的错误

  在一个事务的运行期间,可能会遇到两种类型的命令错误:

  1、一个命令可能会在被放入队列时失败。因此,事务有可能在调用exec命令之前就发生错误。

   例如,这个命令可能会有语法错误(参数的数量错误、命令名称错误,等等),或者可能会有某些临界条件(例如:如果使用maxmemory指令,为Redis服务器配置内存限制,那么就可能会有内存溢出条件)。 
  2、在调用EXEC命令之后,事务中的某个命令可能会执行失败。例如,我们对某个键执行了错误类型的操作(例如,对一个字符串(String)类型的键执行列表(List)类型的操作)。

  解决方法:可以使用客户端检测第一种类型的错误,在调用exec命令之前,户端可以检查被放入队列的命令的返回值:如果命令的返回值是QUEUE字符串,那么就表示已经正确地将这个命令放入队列;否则,Redis将返回一个错误。如果将某个命令放入队列时发生错误,那么大多数客户端将会中止事务,并且丢弃这个事务。

  

  redis为什么不支持回滚

  redis在事务运行期间,虽然redis命令可能会执行失败,但是redis仍然会执行事务中余下的其他命令,而不会执行回滚。

  这是为什么?

  只有当被调用的Redis命令有语法错误时,这条命令才会执行失败(在将这个命令放入事务队列期间,redis能都发现此类问题),或者对某个键执行不符合其数据类型的操作:实际上,这就意味着只有程序错误才会导致reedis命令执行失败。这种错误很有可能在程序开发期间发现,一般很少在生产环境发现。

  redis已经在系统内部进行功能简化,这样可以确保更快的运行速度,一次redis不许哟啊事务回滚的能力。

  

  丢弃命令队列

  discard命令可以用来中止事务运行。在这种情况下,不会执行事务中的任何命令,并且会将redis的连接恢复为正常状态

  

  通过cas操作实现乐观锁

   redis使用watch命令实现事务的检查再设置(cas)行为

  作为watch命令的参数的键会收到redis的监控,redis能够检测到它们的变化。在执行exec命令之前,如果redis检测到至少有一个键被修改了,那么整个事务便会终止运行,然后exec命令会返回一个null值,提醒用户事务运行失败。

 

  watch命令详解

  这个命令会使得exec命令在满足某些田间时才会运行事务:我们要求redis只有在所有受监控的键都没有被修改时,才会执行事务。(但是,相同的客户端可能会在事务内部改改这些键,此时这个事务不会终止运行)否则,,redis根本就不会进入事务。(注意,如果你使用watch命令监控一个易失性的键,然后在你监控这个键之后,redis在使这个件过期,那么exec命令仍然可以正常工作)

  watch命令可以被调用多次,简单来说,所有的watch命令都会在被调用之时立刻对相应的键进行监控,知道exec命令被调用之时位置,你可以在单挑watch命令之中,使用任意数量的键作为命令参数。

  当调用exec命令时,所有的键都会变为未受监控的状态,redis不会管事务是否被中止。当一个客户单来凝结被关闭时,所有的键也都会变为未受监控状态

  话可以使用unwatch命令,这样便能清楚所有的受监控键。当我们对某些键施加乐观锅之后,这个命令有时会变得非常有用。因为,我们可能需要运行一个用来修改这些键的事务,但是在读取这些键的当前内容之后,我们可能不打算继续进行操作,操作,此时便可以使用unwatch命令,清楚所有受监控的键。在运行unwatch命令之后,redis连接便可以再次自由的运行新事物

  redis脚本和事务

  根据定义,redis脚本也是事务型的。因此,可以通过redis事务实现的功能,同样也可以通过redis脚本来实现,而且通常脚本更简单,更快速。

  由于redis从2.6版本才引入脚本特性,而事务特性是很久以前就已经存在的,所以目前的版本才有两个看起来重复的特性。但是,我们不太可能在短时间移除对事务特性的支持。因为,即使不用求助与redis脚本,用户任然能规避竞争状态。华友一个另一个更重要的原因,redis事务特性的实现复杂度是最小的。

  

redis事务

标签:执行   连续   简化   修改   blog   过期   检查   不执行   读取   

原文地址:https://www.cnblogs.com/alighie/p/8289600.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!