首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Redis事务处理机制分析与总结

事务的定义

事务是一组具备原子性操作的命令集合。在这一组命令中,要么全部执行成功,要么全部执行失败。

事务的特点

原子性。原子性指的是事务操作具备原子操作,一个事务里面的 SQL 操作要么全部成功要么全部失败,不能存在一些 SQL 成功,一些 SQL 执行失败。

隔离性。隔离性指的是多个事务之间是相互隔离的,事务之间是互不受影响的。

持久性。持久性指的是事务一旦提交,就不能进行回滚(撤回),永久的保存在磁盘中。

一致性。一致性指的是事务操作前后必须满足业务约束。

Redis事务执行逻辑

Redis在事务中的命令是添加到一个命令队列里面,等待事务提交之后,则一一执行命令队列里面的命令。

Redis事务命令

multi:开启事务。

exec:提交当前事务。

discard:取消当前事务。

watch:监听key是否在事务开启之前被其他命令修改,如果被修改去不处理事务内的操作。

unwatch:取消监听key是否在事务开启之前被其他的命令修改。

命令演示

事务执行流程。

客户端一:负责开启事务并写入缓存数据。

127.0.0.1:6379> multi

OK

127.0.0.1:6379> set user:id:1 1

QUEUED

127.0.0.1:6379> exec

1) OK

事务执行exec命令返回的是,事务中执行的命令数量以及对应的结果。

客户端二:负责读取缓存中的数据。

# 客户端一执行set之后,执行exec之前。

127.0.0.1:6379> get user:id:1

(nil)

# 客户端执行exec之后。

127.0.0.1:6379> get user:id:1

"1"

watch对key监听。

客户端一:负责开启事务,并使用watch监听key。

# 监听key之前查看值

127.0.0.1:6379> get age

"1"

# 开启监听

127.0.0.1:6379> watch age

OK

# 开启事务

127.0.0.1:6379> multi

OK

# 修改被监听的key值

127.0.0.1:6379> set age 2

QUEUED

# 提交事务(发现返回的是nil,表示未执行成功。)

127.0.0.1:6379> exec

(nil)

# 重新获取监听的key值

127.0.0.1:6379> get age

"3"

客户端二:负责修改客户端一中监听的key。

# 在客户端一执行watch命令,开启事务之后,提交事务之前执行。

127.0.0.1:6379> set age 3

OK

# 在客户端一执行exec命令之后执行。

127.0.0.1:6379> get age

"3"

通过2中的演示,你会发现在事务开启之前对key做了监听。事务正常提交之后,被监听的key在事务中执行的命令是不会被执行的。unwatch对监听的key,取消监听事件。此时的取消监听不能放在事务中,只能在事务开启之前对key的监听事件做取消。事务命令异常处理

事务原子性演示

命令错误的原子性。

127.0.0.1:6379> multi

OK

127.0.0.1:6379> set user:name zhangsan

QUEUED

127.0.0.1:6379> set user:age 1

QUEUED

127.0.0.1:6379> set user:sex max

QUEUED

# 执行一条命令错误的操作

127.0.0.1:6379> set a

(error) ERR wrong number of arguments for 'set' command

# 提交事务

127.0.0.1:6379> exec

(error) EXECABORT Transaction discarded because of previous errors.

127.0.0.1:6379> keys *

1) "user:id:1"

2) "name"

3) "age"

通过上面的演示,在事务中执行一条错误的语法命令,整个事务都将不会被执行。

内部语法使用错误。

127.0.0.1:6379> get name

"zhangsan"

127.0.0.1:6379> multi

OK

127.0.0.1:6379> set mu:id 1

QUEUED

# 执行一个语法不当的操作

127.0.0.1:6379> incr name

QUEUED

127.0.0.1:6379> set mu:age 2

QUEUED

127.0.0.1:6379> exec

1) OK

2) (error) ERR value is not an integer or out of range

3) OK

通过上面的演示,在事务中执行了一条语法不当的的操作,最终提交事务后。事务中的正确命令依旧不被执行了。这不符合事务原子性的特点。

事务原子性总结。

a. 当事务中存在语法使用不当的情况时,事务会跳过当前的命令。其他的正确命令依旧被执行。

b. Redis中的事务并非一定满足原子性的特点。

c. 在事务中,执行的命令,Redis只会检测是否是一个合法的命令。如果合法则添加到命令队列,如果不合法则直接阻止整个事务的执行。

常见问题总结

MySQL中的事务与Redis事务的区别

Redis事务与Mysql事务我们知道关系性数据库Mysql中具有事务的四大特性:「原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)」。

但是Redis的事务为了保证Redis除了客户端的请求高效,去除了传统关系型数据库的「事务回滚、加锁、解锁」这些消耗性能的操作,Redis的事务实现简单。

原子性中Redis的事务只能保证单个命令的原子性,多个命令就无法保证,如上面索道的运行时错误,即使中间有运行时错误出现也会正确的执行后面正确的命令,不具有回滚操作。

既然没有了原子性,数据的一致性也就无法保证,这些都需要程序员自己手动去实现。Reids在进行事务的时候,不会被中断知道事务的运行结束,也具有一定的隔离性,并且Redis也能持久化数据。

文章部分素材源自: 卡二条的技术圈

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20210119A04GOL00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券