• 你应该知道的Redis事务


    大家好,我是七淅。

    如果你了解过关系型数据库事务的话,相信这篇文章对你来说是很容易理解的了。具体什么是事务我就不说不多了,直接讲 Redis 事务相关的部分。

    首先,我们先来看下,Redis 是怎么执行事务的。

    1. 事务执行过程

    show code:

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set a test1
    QUEUED
    127.0.0.1:6379> set b test2
    QUEUED
    127.0.0.1:6379> exec
    1) OK
    2) OK
    127.0.0.1:6379> get a
    "test1"
    127.0.0.1:6379> get b
    "test2"
    

    一个事务的开始到结束会经过以下 3 个过程

    1. 事务开始
    2. 命令入队
    3. 事务执行

    结合上面的例子,用人话介绍这 3 个过程就是:

    Redis 执行 multi 命令标志事务开始。

    当客户端切换至事务状态后,服务端会将除了 exec、discard(取消事务,放弃执行事务块内的所有命令)、watch 和 multi 以外的命令放进一个先进先出的事务队列中。即上面例子的 2 个 set 命令会被放进队列,并返回 QUEUED 给客户端。

    当客户端发送 exec 命令时,服务端会立即执行该命令。遍历这个客户端的事务队列,执行队列保存的所有命令。最后将执行命令所得结果返回给客户端。

    2. Redis 事务和关系型事务的区别

    两者最大区别就是 Redis 事务不支持回滚。即使事务队列中某个命令在执行期间发生了错误,事务也会继续执行,直到事务队列中所有命令执行完成。

    文字貌似不够直观,没事,看下面的例子你就马上明白了。

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set msg test
    QUEUED
    127.0.0.1:6379> lpop msg
    QUEUED
    127.0.0.1:6379> exec
    1) OK
    2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
    127.0.0.1:6379> get msg
    "test"      // 不受后面错误命令影响
    

    PS:如果客户端向事务入列一个错误的命令(比如输入一个不存在的命令,像:sett 命令),那么该事务将不被服务端执行。该情况是入队错误,上面例子是执行错误的情况。

    3. watch

    提到 redis 事务,就不得不提 watch 命令了。

    该命令是一个乐观锁,只能在客户端进入事务状态之前执行。

    作用是 exec 命令执行之前,监视任何数量个键,并在 exec 命令执行时,检查被监视的键是否至少有一个已经被修改过。若是则拒绝执行事务,否则执行。

    当 exec 执行完成后,这次事务也就结束了。

    我们依旧来看一个简单的栗子:

    127.0.0.1:6379> SET msg test  //设置 msg 的值
    OK
    127.0.0.1:6379> WATCH msg //监视 msg
    OK
    127.0.0.1:6379> SET msg test2 //修改 msg 的值(或其他客户端在该客户端执行 exec 命令之前修改该值)
    OK
    127.0.0.1:6379> MULTI
    OK
    127.0.0.1:6379> SET msg test3
    QUEUED
    127.0.0.1:6379> GET msg
    QUEUED
    127.0.0.1:6379> EXEC 
    (nil)   //执行失败
    

    如果觉得文章不错,希望能得到你的关注:七淅在学Java

  • 相关阅读:
    Git实战技巧-如何将暂存区的多个功能代码分成多次提交
    Import Error: from torchtext.data import to_map_style_dataset解决方案
    elasticsearch导出和导入数据
    什么是AI-Chat?如何用AI帮你画图、写文章、写PPT?详细教程来了
    Go-Excelize API源码阅读(三十九)——SetCellHyperLink
    每周推荐短视频:为什么产品开发需要数字化?如何做到数字化?
    82-FastDFS详解
    vue中的provide/inject你知道吗(vue2、vue3)?
    java用双大括构造方式进行号初始化赋值操作
    【生物信息学】使用谱聚类(Spectral Clustering)算法进行聚类分析
  • 原文地址:https://www.cnblogs.com/czd-xi/p/16071242.html