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

    Redis 事务

    Redis 事务:一次执行多个命令

    Redis事务工作特点:

    • 批量操作放入队列缓存。(执行有顺序)
    • 事务中任意命令执行失败,其余的命令依然被执行。(不保证原子性)
    • 在事务执行过程,其他命令请求不会插入到事务执行命令序列中。(排他性)

    三个阶段:

    • 开始事务。(multi)
    • 命令入队。
    • 执行事务。(exec)

    实例

    127.0.0.1:6379> multi #开启事务
    OK
    
    ########## 命令入队 开始##################
    127.0.0.1:6379(TX)> set k1 v1
    QUEUED
    127.0.0.1:6379(TX)> set k2 v2
    QUEUED
    127.0.0.1:6379(TX)> get k1
    QUEUED
    127.0.0.1:6379(TX)> set k3 v3
    QUEUED
    ########### 命令入队 结束 #################
    
    127.0.0.1:6379(TX)> exec # 执行事务
    1) OK
    2) OK
    3) "v1"
    4) OK

    放弃事务

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> set k4 v4
    QUEUED
    127.0.0.1:6379(TX)> set k5 v5
    QUEUED
    127.0.0.1:6379(TX)> discard #取消事务
    OK
    127.0.0.1:6379> get k4 ####取消执行事务中所有命令,k4就会没值
    (nil)

    命令有误,事务中所有命令都不执行

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> set k1 v1
    QUEUED
    127.0.0.1:6379(TX)> getset k2 #命令错误
    (error) ERR wrong number of arguments for 'getset' command
    127.0.0.1:6379(TX)> set k3 v3
    QUEUED
    127.0.0.1:6379(TX)> exec
    (error) EXECABORT Transaction discarded because of previous errors.

    运行时异常

    127.0.0.1:6379> set k1 v1 
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> INCR k1 #k1自加一,必须时数值,有错误,不影响其他命令执行
    QUEUED
    127.0.0.1:6379(TX)> set k2 v2 
    QUEUED
    127.0.0.1:6379(TX)> exec
    1) (error) ERR value is not an integer or out of range
    2) OK
    127.0.0.1:6379> get k2
    "v2"

    Redis 事务--锁

    Watch:相当于乐观锁

    通过监视key的值是否改变来决定事务能否正常提交

    实例

    正常执行

    127.0.0.1:6379> set money 100
    OK
    127.0.0.1:6379> set out 0
    OK
    127.0.0.1:6379> watch money #监视money
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> decrby money 20
    QUEUED
    127.0.0.1:6379(TX)> incrby out 20
    QUEUED
    127.0.0.1:6379(TX)> exec #正常执行
    1) (integer) 80
    2) (integer) 20

    事务正常执行完成后,watch监视结束

    多线程操作

    127.0.0.1:6379> watch money
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> DECRBY money 50
    QUEUED
    127.0.0.1:6379(TX)> INCRBY out 50
    QUEUED
    127.0.0.1:6379(TX)> 

    事务没有执行,另一个线程修改了监视的key

    执行事务

    127.0.0.1:6379(TX)> exec #执行失败
    (nil)

    重新执行事务,使用UNWATCH命令(用于取消 WATCH 命令对所有 key 的监视)来保证下一个事务的执行不会受到影响

    127.0.0.1:6379> watch money #开启监视
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> DECRBY money 50
    QUEUED
    127.0.0.1:6379(TX)> INCRBY out 50
    QUEUED
    127.0.0.1:6379(TX)> exec # 执行之前,另一个线程执行了 set money 200
    (nil)
    127.0.0.1:6379> UNWATCH  #取消 WATCH 命令对所有 key 的监视
    OK
    127.0.0.1:6379> WATCH money #开启监视
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379(TX)> DECRBY money 50
    QUEUED
    127.0.0.1:6379(TX)> INCRBY out 50
    QUEUED
    127.0.0.1:6379(TX)> exec
    1) (integer) 150
    2) (integer) 50

    分布式锁(setnx)

    利用setnx命令的特征(存在Key则返回设置失败,不存在Key则返回设置成功),并通过del命令释放锁。

    127.0.0.1:6379> set num 10
    OK
    127.0.0.1:6379> setnx lock-num 2 #设置key
    (integer) 1
    127.0.0.1:6379> incrby num -1
    (integer) 9
    127.0.0.1:6379> del lock-num #释放,如果不释放的话,就无法再次通过setnx设置key
    (integer) 1
    127.0.0.1:6379> setnx lock-num 1 
    (integer) 1
    127.0.0.1:6379> setnx lock-num 1
    (integer) 0

    使用setnx可能会出现忘记释放的情况,需要针对key设置有效时间

    • expire lock-key second
    • pexpire lock-key milliseconds
    127.0.0.1:6379> setnx lock-num 1
    (integer) 0
    127.0.0.1:6379> expire lock-num 1
    (integer) 1
    127.0.0.1:6379> setnx lock-num 1
    (integer) 1

     由于操作通常都是微秒或毫秒级,因此该锁定时间不宜设置过大。具体时间需要业务测试后确认。

     例如:持有锁的操作最长执行时间127ms,最短执行时间7ms。

     测试百万次最长执行时间对应命令的最大耗时,测试百万次网络延迟平均耗时

     锁时间设定推荐:最大耗时*120%+平均网络延迟*110%

     如果业务最大耗时<<网络平均延迟,通常为2个数量级,取其中单个耗时较长即可

  • 相关阅读:
    Objective
    ios 贝塞尔画图
    M端的飞行宝石代码(启发性代码)
    T端单机定时间随机召唤生物的脚本
    T端升级宝石
    Xcode中如何屏蔽某个源文件的编译警告信息
    xcode合并模拟器和真机静态库的编译
    layoutSubviews setNeedsDisplay
    限制只能输入数字字母
    正确使用Block避免Cycle Retain和Crash
  • 原文地址:https://www.cnblogs.com/WarBlog/p/15245561.html
Copyright © 2011-2022 走看看