• Redis 事务


    Redis事务

    一、概念

    Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中不会被其他客户端发送来的命令请求所打断。Redis事务的主要作用就是串联多个命令防止别的命令插队

    二、特点

    1. Redis 事务没有隔离级别的概念
    2. 所有的命令在事务中,并没有直接被运行,只有发起执行命令时才会执行
    3. Redis 单条命令式保存原子性,但事务不保证原子性
    常用命令
    命令描述
    multi标记一个事务的开始
    exec执行所有事务块内的命令
    discard取消事务,放弃执行事务块内的所有命令
    watch key/[key]监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。类似乐观锁
    unwatch取消watch命令对所有 key 的监视。
    • 正常执行事务
    =========================正常执行事务
    127.0.0.1:6379> multi # 开启事务
    OK
    127.0.0.1:6379> set k1 v1 # 命令入队
    QUEUED
    127.0.0.1:6379> set k2 v2
    QUEUED
    127.0.0.1:6379> get k2
    QUEUED
    127.0.0.1:6379> set k3 v3
    QUEUED
    127.0.0.1:6379> exec # 执行事务
    1) OK
    2) OK
    3) "v2"
    4) OK
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 放弃事务
    =========================放弃事务
    127.0.0.1:6379> multi # 开启事务
    OK
    127.0.0.1:6379> set k1 v1
    QUEUED
    127.0.0.1:6379> set k2 v2
    QUEUED
    127.0.0.1:6379> set k4 v4
    QUEUED
    127.0.0.1:6379> DISCARD # 取消事务
    OK
    127.0.0.1:6379> get k4 # 事务队列中命令都不会被执行!
    (nil)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 编译型异常(代码有问题! 命令有错!)事务中所有的命令都不会被执行!
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set k1 v1
    QUEUED
    127.0.0.1:6379> set k2 v2
    QUEUED
    127.0.0.1:6379> set k3 v3
    QUEUED
    127.0.0.1:6379> getset k3
    # 错误的命令
    (error) ERR wrong number of arguments for 'getset' command
    127.0.0.1:6379> set k4 v4
    QUEUED
    127.0.0.1:6379> set k5 v5
    QUEUED
    127.0.0.1:6379> exec # 执行事务报错!
    (error) EXECABORT Transaction discarded because of previous errors.
    127.0.0.1:6379> get k5 # 所有的命令都不会被执行!
    (nil)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 运行时异常,如果事务队列中存在语法性,那么执行命令的时候其他命令是可以正常执行的,错误命令抛出异常!
    127.0.0.1:6379> set k1 "v1"
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> incr k1 # 会执行的时候失败!
    QUEUED
    127.0.0.1:6379> set k2 v2
    QUEUED
    127.0.0.1:6379> set k3 v3
    QUEUED
    127.0.0.1:6379> get k3
    QUEUED
    127.0.0.1:6379> exec
    1) (error) ERR value is not an integer or out of range
    # 虽然第一条命令报错了,但是依旧正常执行成功了!
    2) OK
    3) OK
    4) "v3"
    127.0.0.1:6379> get k2
    "v2"
    127.0.0.1:6379> get k3
    "v3"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    三、为什么添加事务

    保证某些命令,成功时一起提交,失败时同时回滚

    解决方案:

    悲观锁

    悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁**,表锁等,读锁写锁等,都是在做操作之前先上锁

    乐观锁

    乐观锁**(Optimistic Lock)** 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量**。Redis就是利用这种check-and-set机制实现事务的

    # 在执行multi之前,先执行watch key1 [key2],可以监视一个(或多个) key ,如果在事务执行之前这# key 被其他命令所改动,那么事务将被打断
    # 使用
    =========================watch演示,启动两个客户端
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    Java---刷题01
    路径操作 合法路径名
    Java 中对日期时间按区间定位
    创建TCP通信与粘包问题解决
    第三方软件测评报告怎么做?
    VTK基本数据结构
    21天学习挑战赛-剖析快速排序
    第一届长城杯半决赛wp和AWD笔记
    芯片学习记录AM26LS31INSR
    网络安全——使用Linux系统命令对后门端口进行查杀
  • 原文地址:https://blog.csdn.net/weixin_62587914/article/details/132727408