【二十六】redis之事务、事务特性、与pipeline比较,与Lua脚本比较

一、redis事务的特性

1.原子性

这里的原子性跟mysql的原子性不一样。

redis事务的原子性是说的:一次事务提交的多个命令,要么都不执行(watch发现某个key的值变了则不开始执行),要么所有的命令都执行(一旦开始执行事务,事务中所有的命令都会执行,即使有命令报错了,后面的命令也会执行)

报错不回滚! 

不回滚的原因:

● Redis 命令只会因为错误的语法而失败,失败的命令是由编程错误造成的。而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。

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

2.持久性

只在特殊情况下有持久性。也就是做了持久化之后。且用AOF持久化,用always策略,保证每次操作都持久化。

3.隔离性

4.一致性

二、比较

1.redis事务跟redis pipeline相比

1.pipeline是只有一次网络开销执行多个命令,而redis事务是N次网络开销执行N次命令。

2.pipeline不具备原子性,redis的事务具备原子性。

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.WATCH

WATCH 命令可以为 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,发现有命令报错了(比如:事务中的命令可能处理了错误类型的键,比如将列表命令用在了字符串键上面)

 

这里可以看到虽然第二条命令报错了,但是第三条命令也执行,第一条命令也执行了没有回滚

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Lua脚本是一种轻量级的脚本语言,常用于嵌入式系统和游戏开发中。它具有以下特点: 1. 简洁高效:Lua脚本语法简单,学习曲线低,执行速度快。 2. 可扩展性:Lua支持通过C/C++扩展其功能,可以方便地与其他语言进行交互。 3. 跨平台性:Lua脚本可以在多个操作系统上运行,包括Windows、Linux、Mac等。 管道(Pipeline)是一种用于在Redis数据库中执行多个命令的机制。它的优点包括: 1. 减少网络开销:通过将多个命令打包发送到Redis服务器,减少了网络通信的开销。 2. 原子性操作:Redis的管道可以保证多个命令的原子性执行,避免了并发操作带来的问题。 3. 提高性能:通过批量执行多个命令,可以提高Redis的性能。 事务(Transaction)是Redis中用于执行一系列命令的机制,它的优点包括: 1. 原子性操作:Redis事务可以保证一系列命令的原子性执行,要么全部执行成功,要么全部失败。 2. 高效性能:事务中的命令在提交之前不会立即执行,而是在提交时一次性执行,减少了网络通信的开销。 3. 锁定资源:在事务执行期间,Redis会对相关资源进行锁定,避免了其他客户端对同一资源的并发访问。 然而,管道和事务也存在一些缺点: 1. 管道的原子性:虽然管道可以批量执行多个命令,但无法保证这些命令的原子性执行,如果其中某个命令执行失败,后续命令可能会继续执行。 2. 事务的回滚:虽然事务可以保证一系列命令的原子性执行,但如果在事务执行过程中出现错误,整个事务会被回滚,导致之前执行的命令无效。 3. 网络延迟:由于管道和事务需要将多个命令打包发送到Redis服务器,如果网络延迟较高,可能会导致整体性能下降。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值