zoukankan      html  css  js  c++  java
  • redis事务

    简介

    可以一次执行多个命令,本质是一组命令的集合.
    一个事务中的所有命令都会序列化,按顺序的串行化执行而不会被其他命令插入,不许加塞
    

    作用

    在一个队列中,一次性,顺序性,排他性的执行一系列命令
    

    开启事务示例

    remoteSelf:1>multi
    "OK"
    remoteSelf:1>set k1 v1
    "QUEUED"
    remoteSelf:1>set k2 v2
    "QUEUED"
    remoteSelf:1>get k1
    "QUEUED"
    remoteSelf:1>exec
     1)  "OK"
     2)  "OK"
     3)  "v1"
    

    放弃事务

    remoteSelf:1>mget k1 k2
     1)  "v1"
     2)  "v2"
    remoteSelf:1>multi
    "OK"
    remoteSelf:1>set k1 11
    "QUEUED"
    remoteSelf:1>set k2 22
    "QUEUED"
    remoteSelf:1>discard
    "OK"
    remoteSelf:1>mget k1 k2
     1)  "v1"
     2)  "v2"
    

    一个失败所有的都失败(如果打完命令就报错,此时全部回滚)

    remoteSelf:1>keys *
     1)  "k2"
     2)  "k1"
     3)  "website"
     4)  "zset01"
    remoteSelf:1>multi
    "OK"
    remoteSelf:1>set k3 v3
    "QUEUED"
    remoteSelf:1>set k4 v4
    "QUEUED"
    remoteSelf:1>getset k4
    "ERR wrong number of arguments for 'getset' command"
    remoteSelf:1>exec
    "EXECABORT Transaction discarded because of previous errors."
    remoteSelf:1>keys *
     1)  "k2"
     2)  "k1"
     3)  "website"
     4)  "zset01"
    

    一个失败其他的成功(如果打完命令没有报错,进入队列,运行时报错,则其他的运行成功,报错的失败)

    remoteSelf:1>keys *
     1)  "k2"
     2)  "k1"
     3)  "website"
     4)  "zset01"
    remoteSelf:1>mget k1 k2
     1)  "v1"
     2)  "v2"
    remoteSelf:1>multi
    
    "OK"
    remoteSelf:1>incr k1
    "QUEUED"
    remoteSelf:1>set k3 v3
    "QUEUED"
    remoteSelf:1>exec
     1)  "ERR value is not an integer or out of range"
     2)  "OK"
    remoteSelf:1>keys *
     1)  "website"
     2)  "zset01"
     3)  "k1"
     4)  "k2"
     5)  "k3"
    

    watch监控.如果监控的数据发生了改变,则事务失效

    悲观锁

    pessimistic lock,每次拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,
    这样别人想拿这个数据就会block直到拿到锁.
    传统的关系型数据库里边就用到了很多这种锁机制,比如行所,表锁等,读锁,写锁等,都是在操作之前先上锁
    

    乐观锁

    optimistic lock,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,
    可以使用版本号等机制.乐观锁适用于多读的应用类型,这样可以提高吞吐量.
    
    乐观锁策略: 提交版本必须大于记录当前版本才能执行更新
    

    示例

    127.0.0.1:8686[1]> mget balance debt
    1) "100"
    2) "0"
    127.0.0.1:8686[1]> watch balance
    OK
        # watch之后执行更改balance
        remoteSelf:1>set balance "200"
        "OK"
        remoteSelf:1>get balance
        "200"
    127.0.0.1:8686[1]> multi
    OK
    127.0.0.1:8686[1]> decrby balance 20
    QUEUED
    127.0.0.1:8686[1]> incrby debt 20
    QUEUED
    # 执行失败
    127.0.0.1:8686[1]> exec
    (nil)
    
    

    watch

    watch指令,类似乐观锁,事务提交时,如果key的值已经被别的客户端改变,整个事务队列都不会被执行.
    
    通过watch命令在事务执行之前监控了多个keys,倘若在watch之后有任何key的值发生了变化,
    exec命令执行的事务都被放弃,同时返回Nullmulti-bulk应答已通知调用者事务执行失败
    

    exec执行之后会取消对所有key的监控

    127.0.0.1:8686[1]> get test
    "10"
    127.0.0.1:8686[1]> mget balance debt
    1) "200"
    2) "0"
    127.0.0.1:8686[1]> watch balance test
    OK
    127.0.0.1:8686[1]> multi
    OK
        # 另外一个客户端改变balance的值
        remoteSelf:1>set balance "100"
        "OK"
        remoteSelf:1>get balance
        "100"
    127.0.0.1:8686[1]> incr balance
    QUEUED
    127.0.0.1:8686[1]> decr debt
    QUEUED
    # 执行事务失败
    127.0.0.1:8686[1]> exec
    (nil)
    127.0.0.1:8686[1]> mget balance debt
    1) "100"
    2) "0"
    127.0.0.1:8686[1]> get test
    "10"
    # 之前已经监控了test不在监控
        # 修改test的值
        remoteSelf:1>set test "20"
        "OK"
        remoteSelf:1>get test
        "20"
    127.0.0.1:8686[1]> multi
    OK
    127.0.0.1:8686[1]> incr test
    QUEUED
    # 事务执行成功.证明了exec在执行时,会取消对所有key的监控
    127.0.0.1:8686[1]> exec
    1) (integer) 21
    
    

    unwatch会取消所有key的监控

  • 相关阅读:
    register变量
    register变量
    const和volatile是否可以同时修饰一个变量?有什么特殊含义?
    关于多态性和虚函数的理解
    static全局变量与普通的全局变量有什么区别
    《c专家编程》学习笔记
    正则表达式入门学习
    mvc ActionResult
    ASP.NET MVC:通过 FileResult 向 浏览器 发送文件(传)
    Asp.net mvc 中的HttpContext
  • 原文地址:https://www.cnblogs.com/dongshenjun/p/14028379.html
Copyright © 2011-2022 走看看