概要
MULTI、EXEC、DISCARD 和WATCH 是Redis 事务相关命令。一个事务可以同时执行多个命令,有两个重要的保证:
事务是一个单一的、孤立的操作。事务中的所有命令都被序列化并按顺序执行。当事务正在运行时,它不会被其他客户端发送的命令请求中断。事务是一个原子操作。要么执行事务中的所有命令,要么都不执行。 EXEC 命令触发并执行事务中的所有命令。
如果客户端使用MULTI 启动事务,但由于断开连接而无法成功执行EXEC,则事务内的所有命令将不会被执行。
另一方面,如果客户端打开一个事务,然后成功执行EXEC,则该事务内的所有命令都会被执行。当使用AOF 进行持久化时,Redis 使用单个write(2) 命令将事务写入磁盘。
但是,如果Redis服务器由于某种原因被管理员杀死,或者发生某些硬件故障,则只有一些事务命令可能会成功写入磁盘。
如果Redis在重启时检测到AOF文件存在这样的问题,Redis将会退出并报错。
这个问题可以使用redis-check-aof 程序来解决。该程序去除AOF文件中不完整的事务信息,使服务器顺利启动。
从2.2版本开始,Redis还可以通过乐观锁实现CAS(检查和设置)操作。
事务中的错误
使用事务时可能会出现两个错误:
在事务执行EXEC 之前,排队的命令可能会失败。例如,某个命令可能会导致语法错误(参数数量错误、参数名称错误等)或者内存不足等其他错误(如果服务器使用maxmemory设置了最大内存限制),可能会出现更严重的错误。 EXEC 调用后此命令可能会失败。例如,事务中的命令可能会处理错误类型的键,例如对字符串键使用list 命令。对于执行EXEC 之前发生的错误,客户端之前的做法是检查排队命令的返回值。如果入队时命令返回QUEUED,则入队成功,否则入队失败。如果命令在排队期间失败,大多数客户端将停止并取消事务。
然而,从Redis 2.6.5开始,服务器会记录命令排队失败,当客户端调用EXEC命令时,它会拒绝执行并自动放弃事务。
在Redis 2.6.5之前,Redis仅执行事务中成功排队的命令,并忽略未排队的命令。 新的处理方法使得将交易包含在管道中变得更加容易,因为只需要与服务器进行一次通信即可发送交易并读取交易响应。
对于执行EXEC 命令后发生的错误没有特殊处理。即使事务中的特定命令在执行期间遇到错误,事务中的其他命令也会继续执行。
为什么 Redis 不支持回滚(roll back)
如果您有使用关系数据库的经验,那么听到Redis 不会回滚失败的事务并继续执行剩余的命令可能会有点奇怪。
这种方法的优点是:
仅当语法不正确(这些问题在排队时无法发现)或者命令使用了错误类型的键时,Redis 命令才会失败。从实际角度来看,这意味着命令失败是由于编程造成的。这是一个应该在开发过程中捕获的错误,不应该在生产中发生。不需要回滚支持,这有助于保持Redis 内部简单、快速。尽管有些人认为Redis 处理事务的方式可能会引入错误,但需要注意的是,在正常情况下,回滚无法解决由编程错误引起的问题。 例如,如果你原本打算使用INCR 命令将某个key 的值加1,结果不小心加了2,或者对错误类型的key 执行了INCR,则回滚时需要这些没有办法处理情况。
#redis##程序员##面试##分布式#
版权声明:本文由今日头条转载,如有侵犯您的版权,请联系本站编辑删除。