湖南响应式网站推荐长沙大型网站设计公司
news/
2025/10/2 23:59:32/
文章来源:
湖南响应式网站推荐,长沙大型网站设计公司,网站建设必知,网页制作模板html文章目录 Redis 事务1)基本认识2)事务操作1.MULTI2.EXEC3.错误处理4.DISCARD5.WATCH6.SCRIPT Redis 事务
官方文档#xff0c;永远是你学习的第一手资料#xff1a;Redis 事务
1)基本认识 谈到事务#xff0c;大家首先都会联想到 mysql 中复杂但又功能强大的“事务”… 文章目录 Redis 事务1)基本认识2)事务操作1.MULTI2.EXEC3.错误处理4.DISCARD5.WATCH6.SCRIPT Redis 事务
官方文档永远是你学习的第一手资料Redis 事务
1)基本认识 谈到事务大家首先都会联想到 mysql 中复杂但又功能强大的“事务”和 mysql 相比redis 所提供的事务简直就是个“弟弟”。我们从 mysql 事务的四大基本特点进行比较
原子性 原子性最初的含义就是把多个操作打包到一起要么全部执行要么全部不执行。但是mysql 在原子性这条道路上走的更远它要求多个操作要么全部执行成功要么全部不执行如果其中任一操作执行失败都会 rollback 确保数据的一致性。 Redis 事务可以说具有原子性也可以说没有这是一个理解角度的问题。Redis 事务确实可以将多个操作打包一起执行从这方面谈Redis 是具有原子性的但是和 mysql 不同Redis 事务并不保证所有命令执行成功由于 mysql 的标杆作用“拉高”了原子性的标准从这一方面说Redis 并不具有原子性。 早些版本的 Redis 官网中明确提出了 Redis 事务具有原子性但现在去看官网已经把第一句删掉了。看连 Redis 官方都 “怂了”所以我们还是倾向于认为 Redis 不具有原子性 那为什么 Redis 不提供和 mysql 一样强大的事务机制呢首先 mysql 为了实现事务机制付出了巨大的代价而 Redis 则是主打一个轻量简单如果和 mysql 一样就丢了自己的特色那又怎么从这么多数据库中冲杀出来呢
一致性 由于 Redis 并不提供事务回滚机制当其中某些操作失败时就会造成数据不一致的问题。例如以下这个场景张三给李四转账 1000 元。张三余额 -1000 的操作成功但是李四余额 1000 的操作失败而 redis 并不会因为操作执行失败而回滚数据从而导致数据不一致的问题发生
持久性 mysql 中又 redo log 保证事务的持久性但是 redis 事务本身并不具有持久性持久化还得依赖redis的 rdb 或者 aof 机制。但是否开启持久化是redis-server自己的决定和事务本身无关
隔离性 Redis 没有也不需要隔离性。隔离性是针对并发读写的问题而引入了而 Redis 是一个单进程的数据库不存在这方面的烦恼。
2)事务操作
1.MULTI multi 指令用于开启一个事务 127.0.0.1:6379 multi
OKRedis 服务端为每一个客户端维护一个事务命令队列multi 后所有命令(除了 exec)都会被添加到队列中而不是立即执行queued 状态 127.0.0.1:6379 set key1 1
QUEUED
127.0.0.1:6379 set key1 2
QUEUED2.EXEC exec 指令用于按次序一次性执行事务队列中命令 127.0.0.1:6379 exec
1) OK
2) OK
127.0.0.1:6379 get key1
13.错误处理
在 Redis 事务中存在两种类型的错误 在调用 exec 前发生错误例如某个指令中存在语法错误。当这种错误发生时整个事务都会被直接丢弃 127.0.0.1:6379 multi
OK
127.0.0.1:6379 get key1
QUEUED
127.0.0.1:6379 abc
(error) ERR unknown command abc, with args beginning with:
127.0.0.1:6379 exec
(error) EXECABORT Transaction discarded because of previous errors.在调用 exec 期间发生的错误。在这种情况下Redis 会继续执行剩余的命令不管某些命令是否失败。 127.0.0.1:6379 FLUSHALL
OK
127.0.0.1:6379 multi
OK
127.0.0.1:6379 set key1 1
QUEUED
127.0.0.1:6379 LPOP key1
QUEUED
127.0.0.1:6379 set key2 2
QUEUED
127.0.0.1:6379 get key2
QUEUED
127.0.0.1:6379 EXEC
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) OK
4) 2上面的案例也验证了 Redis 事务只能保证多条一起执行但并不保证所有的命令都会执行成功。失败了也不会数据回滚因而存在一致性的问题
4.DISCARD discard 指令用于终止取消当前正在执行的事务队列中的所有指令都会被直接丢弃 127.0.0.1:6379 multi
OK
127.0.0.1:6379 get key1
QUEUED
127.0.0.1:6379 get key2
QUEUED
127.0.0.1:6379 discard
OK
127.0.0.1:6379 exec
(error) ERR EXEC without MULTI当前没有正在执行的事务则 discard 指令无效 127.0.0.1:6379 discard
(error) ERR DISCARD without MULTI5.WATCH
用法 在执行事务期间某个键值被其他客户端修改了其结果就容易令人产生歧义例如下面这个场景 timeclient_1client_2t1execute command multit2execute command set key1 1……t3execute command set key1 2t4execute command exec watch 与事务配合使用它允许你监视多个 key如果在事务的执行期间任何一个键被其他客户端修改都会导致当前事务全部丢弃从而确保了事务执行期间数据的一致性。watch 的作用时间从 multi 开始到执行 exec 结束。 // client1
127.0.0.1:6379 mset key1 1 key2 2
OK
127.0.0.1:6379 watch key1 key2
OK
127.0.0.1:6379 multi
OK
127.0.0.1:6379 mget key1 key2
QUEUED
127.0.0.1:6379 exec
(nil) // 事务执行失败// client2在client1事务执行期间进行如下修改
127.0.0.1:6379 incr key1
(integer) 2
127.0.0.1:6379 decr key2
(integer) 1unwatch 的作用与 watch 相反它用于清除对所有 key 的 “watch”。在执行 exec 或者 client 退出时所有的 key 都会 “unwatched”
原理 watch 本质就是一把乐观锁通过CAS机制实现每个 watched 变量都有一个初始版本号修改变量会让其版本号变大在执行 exec 时会比较当前版本号与 watch 时的版本号是否一致如果不一致说明变量在事务执行期间发生了修改当前事务就会被 discard
案例
下面是官方文档提供的一个使用案例通过 watch 去创造一个新的原子操作
WATCH zset
element ZRANGE zset 0 0
MULTI
ZREM zset element
EXEC从 zset 中删除一个元素有两部1)找到最小的元素 2) 将最小的元素删除。如果删除失败说明最小值被其他客户端修改那么我们就重复上面操作直到删除一个最小值
6.SCRIPT 任何 redis 事务能完成的操作我们都可以使用 redis script 完成。redis script 天生就有把多个指令打包执行的能力感兴趣的可以去网上找找 lua 脚本操作 redis 的教程
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/925426.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!