莫张周刘王 发表于 2024-11-22 10:00:37

Redis中有事务吗?有何不同?

与关系型数据库事务的区别

Redis事务是指将多条命令加入队列,一次批量实行多条命令,每条命令会按次序实行,事务实行过程中不会被其他客户端发来的命令所打断。也就是说,Redis事务就是一次性、次序性、排他性的实行一个队列中的一系列命令。
Redis事务和关系型数据库的事务不太一样,它不保证原子性,也没有隔离级别的概念。
事务不保证原子性,但是Redis命令自己是原子性的

[*]Redis事务没有隔离级别的概念
批量操作在发送 EXEC 命令前被放入队列缓存,并不会被实际实行,也就不存在事务里的查询要看到本领务的更新或其它事务的修改更新操作的标题。(Mysql里的事务的语句不是放入队列,而是直接实行)
[*]Redis不保证原子性
Redis中,单条命令是原子性实行的,但事务不保证原子性,且没有回滚。事务中任意命令实行失败,别的的命令仍会被实行。
Redis事务的运行流程

Redis事务相关命令


[*]Multi :开始事务
[*]Exec :实行事务中的所有命令,即提交;
[*]discard :放弃事务;和回滚不一样,Redis事务不支持回滚。
[*]WATCH:监视Key改变,用于实现乐观锁。如果监视的Key的值改变,事务最终会实行失败。
[*]UNWATCH:放弃监视。
没有隔离级别

当事务开启时,事务期间的命令并没有实行,而是加入队列,只有实行EXEC命令时,事务中的命令才会按照次序实行,也就是说事务间就不会存在数据脏读、不可重复读、幻读的标题,因此就没有隔离级别。
https://seven97-blog.oss-cn-hangzhou.aliyuncs.com/imgs/202404270809647.png
事务不保证原子性

如上图所示,在通过EXEC实行事务时,其中命令实行失败不会影响到其他命令的实行,因此并没有保证同时成功和同时失败的原子操作,尽管这样,Redis事务中也没有提供回滚的支持
https://seven97-blog.oss-cn-hangzhou.aliyuncs.com/imgs/202404270810674.png
官方理由为:保证Redis的性能

[*]事实上如果利用Redis命令语法错误,或是将命令运用在错误的数据类型键上(如对字符串进行加减乘除等),从而导致业务数据有标题,这种情况认为是编程导致的错误,应该在开辟过程中解决,避免在生产情况中发生;
[*]由于不用支持回滚功能,Redis内部简单化,而且还比较快;
多数事务失败是由语法错误大概数据结构类型错误导致的,语法错误说明在命令入队前就进行检测的,而类型错误是在实行时检测的,Redis为提升性能而采用这种简单的事务,这是不同于关系型数据库的,特别要留意区分。Redis之所以保持这样简易的事务,完全是为了保证高并发下的核心标题——性能。
语法错误(编译器错误)

在开启事务后,A的转出操作命令打成了DECRBYa,最终会导致事务提交失败,所有命令都不会实行,A、B保存原值。
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> DECRBYa A 500
(error) ERR unknown command 'DECRBYa', with args beginning with: 'A' '500'
127.0.0.1:6379(TX)> INCRBY B 500
QUEUED
127.0.0.1:6379(TX)> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> mget A B
1) "1000"
2) "100"
127.0.0.1:6379>类型错误(运行时错误)

在运行时检测类型错误,此时势务并没有回滚,而是跳过错误命令继续实行, 效果B值改变、A保存原值。
https://seven97-blog.oss-cn-hangzhou.aliyuncs.com/imgs/202404270810644.png
小结


[*]当事务中命令语法利用错误时,最终会导致事务实行不成功,即事务内所有命令都不实行;
[*]当事务中命令知识逻辑错误,就比如给字符串做加减乘除操作时,只能在实行过程中发现错误,这种事务实行中失败的命令不影响其他命令的实行。
利用WATCH实现乐观锁

WATCH通过监视指定Redis Key,如果没有改变,就实行成功,如果发现对应值发生改变,事务就会实行失败,如下图:
https://seven97-blog.oss-cn-hangzhou.aliyuncs.com/imgs/202404270810967.png
三种方式可以取消监视:

[*]事务实行之后,不管是否实行成功还好是失败,都会取消对应的监视;
[*]当监视的客户端断开毗连时,也会取消监视;
[*]可以手动UNWATCH取消所有Key的监视;
面试题专栏

Java面试题专栏已上线,欢迎访问。

[*]如果你不知道简历怎么写,简历项目不知道怎么包装;
[*]如果简历中有些内容你不知道该不应写上去;
[*]如果有些综合性标题你不知道怎么答;
那么可以私信我,我会尽我所能资助你。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Redis中有事务吗?有何不同?