Redis 事务

  1. redis事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

  2. redis事务还能保证事务中的命令要么全部被执行,要么全部都不执行。

    

redis事务主要包括multi、exec、discard和watch命令。

multi命令用来开启一个事务,当multi执行之后,客户端可以继续向服务器发送多条命令,这些命令会缓存在队列里面,只有当执行exec命令时,这些命令才会执行。

而discard命令可以清空事务队列,放弃执行事务。

一个使用multi、exec执行事务的例子:

exec 命令的回复是一个数组, 数组中的每个元素都是执行事务中的命令所产生的回复。其中,回复元素的先后顺序和命令发送的先后顺序一致。

当客户端处于事务状态时, 所有传入的命令都会返回一个内容为 QUEUED 的状态回复,这些被入队的命令将在 exec  命令被调用时执行。

 

事务的错误处理

执行事务时可能会遇上以下两种错误:

  1. 语法错误,例如命令不存在或者命令参数个数不对。

 

     如上图,只要有一个命令语法有错,执行exec命令后redis就会直接返回错误,语法正确的命令也不会执行。

   2. 运行错误,命令可能在 exec调用之后失败。例入事务中的命令可能处理了错误类型的键,比如将列表命令用在了字符串键上面。

         

   如上图,在 exec 命令执行之后所产生的错误, 并没有对它们进行特别处理: 即使事务中有某个/某些命令在执行时产生了错误, 事务中的其他命令仍然会继续执行。

 

为什么redis不支持回滚

针对上述第二种错误处理,“redis 在事务失败时不进行回滚,而是继续执行余下的命令”这种做法可能会让你觉得有点奇怪。

以下是这种做法的优点(摘抄自http://redisdoc.com/):

Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。

因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

有种观点认为 Redis 处理事务的做法会产生 bug , 然而需要注意的是, 在通常情况下, 回滚并不能解决编程错误带来的问题。 举个例子, 如果你本来想通过 INCR 命令将键的值加上 1 , 却不小心加上了 2 , 又或者对错误类型的键执行了 INCR , 回滚是没有办法处理这些情况的。

鉴于没有任何机制能避免程序员自己造成的错误, 并且这类错误通常不会在生产环境中出现, 所以 Redis 选择了更简单、更快速的无回滚方式来处理事务。

放弃事务

当执行 discard 命令时,事务会被放弃,事务队列会被清空,并且客户端会从事务状态中退出:

如上图,当执行discard命令后,get 获取 a的值,返回nil,无此键。

Watch 命令

被 watch 的键会被监视,并会发觉这些键是否被改动过了。 如果有至少一个被监视的键在 exec 执行之前被修改了,那么整个事务都会被取消,exec 返回nil表示事务已经失败。

watch 使得 exec 命令需要有条件地执行: 事务只能在所有被监视键都没有被修改的前提下执行, 如果这个前提不能满足的话,事务就不会被执行。

如果你使用 watch监视了一个带过期时间的键, 那么即使这个键过期了, 事务仍然可以正常执行。

 

过期时间

Redis可以设置一个健的过期时间,到时间后redis会自动删除它。

 

如上图,expire命令可以设置键的过期时间,ttl命令查看一个健还有多久的时间被删除,返回剩余秒。Persist 命令可取消过期时间设置。

转载于:https://www.cnblogs.com/zhangzhi19861216/p/4711063.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值