在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
一、redis事务的特性1.原子性这里的原子性跟mysql的原子性不一样。 redis事务的原子性是说的:一次事务提交的多个命令,要么都不执行(watch发现某个key的值变了则不开始执行),要么所有的命令都执行(一旦开始执行事务,事务中所有的命令都会执行,即使有命令报错了,后面的命令也会执行) 报错不回滚! 不回滚的原因:
2.持久性只在特殊情况下有持久性。也就是做了持久化之后。且用AOF持久化,用always策略,保证每次操作都持久化。 3.隔离性4.一致性二、比较1.redis事务跟redis pipeline相比
pipeline可能存在的场景是: pipeline 中执行命令1 命令2 命令3 其他非pinpeline执行命令4 命令5 最后的结果可能是 命令1 命令4 命令2 命令5 命令3 2.redis事务跟redis lua相比redis用multi命令开启事务后,后面的命令都是放入队列中,遇到exec再真正的执行,放入队列中的命令不会立马返回结果,只是返回QUEUED表示成功放入命令。EXEC统一执行了之后统一返回每个命令的结果。 换句话说,如果我们想实现这个场景,用redis的事务就实现不了: 得到key=age1的数据,如果该数据存在且该数据为100,那么删掉该数据,否则不做操作。 因为在事务中get age1命令返回的时QUEUED,并不是返回的age1的值 而这个场景用redis lua脚本可以实现 三、事务相关的命令1.MULTI用于标记事务的开始,其后执行的命令都将被存入命令队列,直到执行EXEC时这些命令才会被执行。或者遇到DISCARD命令 可以看到开启事务后,每次命令只是进入了该事务的命令队列,返回的是QUEUED,得执行了EXEC后才真的执行这些命令返回命令对应的执行结果。 2.EXEC执行在一个事务内命令队列中的所有命令,同时讲当前状态回复为正常状态,即是非事务状态。 如果在事务中执行了watch命令,那么只有当watch所监控的keys没有被修改的前提下,EXEC命令才能执行事务队列中所有的命令,否则EXEC讲放弃当前事务中的所有命令。 3.DISCARD回滚事务队列中的所有命令,同时再将当前连接的事务状态恢复为正常状态,即是非事务状态。 如果WATCH命令被使用,该命令将UNWATCH所有的keys 可以看到并没有返回test_key_1的结果,也没有执行set test_key_2 4.WATCHWATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为。 在MULTI命令执行前,可以WATCH指定待监控的keys,然后在执行EXEC前,如果被监控的keys发生修改,那么整个事务都会被取消, EXEC 返回空多条批量回复(null multi-bulk reply)来表示事务已经失败。 WATCH 使得 EXEC 命令需要有条件地执行: 事务只能在所有被监视键都没有被修改的前提下执行, 如果这个前提不能满足的话,事务就不会被执行 5.UNWATCH取消当前事务中指定监控的keys,如果执行了EXEC或DISCARD命令,则无需再手工执行UNWATCH命令了。 6.测试报错1.在执行EXEC前,如果有很明显的错误,则不会开始执行事务 比如事务在执行 EXEC 之前,入队的命令可能会出错(比如:命令产生语法错误(参数数量错误,参数名错误,等等)) 2.已经开始执行EXEC,发现有命令报错了(比如:事务中的命令可能处理了错误类型的键,比如将列表命令用在了字符串键上面)
这里可以看到虽然第二条命令报错了,但是第三条命令也执行,第一条命令也执行了没有回滚 |
请发表评论