美文网首页
Redis事务锁CAS实现以及深入误区

Redis事务锁CAS实现以及深入误区

作者: JeniusYang | 来源:发表于2017-10-11 19:41 被阅读0次

    Redis中的事务

    Redis的事务没有mysql那么的丰富,但在JAVA web的开发过程中利用mysql事务锁并不能满足应用场景,或者说并不是很简便,例如发放新人大礼包,代金券这种电商场景。

    谈到事务,就跟acid分离不开,Redis事务也较好地满足了一致性和隔离性,但持久性和原子性一直有争议,业务上一般使用redis的组合原子操作来完成事务的原子性,redis事务的几个关键命令:

    MULTI: 开启一个事务,类比于mysql的openSession
    EXEC: 提交一个事务,类比于mysql的commit
    DISCARD: 取消一个事务,类比于mysql的rollback
    WATCH:监控一个key,与redis事务机制结合使用,形成原子锁
    

    Redis实现CAS(Check-And-Set)的测试场景

    • 场景一:
    10.185.0.120:6932> watch test
    OK
    // 另一个clinet 对test执行incr操作后
    //在当前clinet继续操作
    10.185.0.120:6932> multi
    OK
    10.185.0.120:6932> exec
    (nil)
    
    • 场景二:
    10.185.0.120:6932> watch test
    OK
    // 另一个clinet 执行下面操作
    10.185.0.120:6932> multi
    OK
    10.185.0.120:6932> incr test
    QUEUED
    10.185.0.120:6932> exec
    (nil)
    
    • 场景三:
    10.185.0.120:6932> get test
    "88"
    10.185.0.120:6932> watch test
    OK
    10.185.0.120:6932> incr test
    (integer) 89
    10.185.0.120:6932> multi
    OK
    10.185.0.120:6932> incr test
    QUEUED
    10.185.0.120:6932> exec
    (nil)
    
    • 场景四:
    10.185.0.120:6932> get test
    "89"
    10.185.0.120:6932> wacth test
    OK
    10.185.0.120:6932> multi
    OK
    10.185.0.120:6932> incr test
    QUEUED
    10.185.0.120:6932> exec
    1) (integer) 90
    

    对上面五种场景总结:

    1. client A watch,clientB set/incr等等操作,clientA 中multi-exec会失败
    2. client A watch,clientB multi-set/incr-exec 也会失败
    3. client A 中watch后,进行incr/set操作后,再进行multi-incr-exec 也会失败
    4. client A watch-multi-incr/set-exec 成功
    

    CAS中的误区理解

    这里需要说明的是,Redis官方文档给出的watch命令的解释:

    we are asking Redis to perform the transaction only if no other client modified any of the WATCHed keys
    

    从场景三可以看出,这里的“other client” 并不一定是另外一个客户端,watch操作执行之后,multi之外任何操作都可以认为是other clinet在操作(即使仍然是在同一个客户端上操作),exec该事务也仍旧会失败

    相关文章

      网友评论

          本文标题:Redis事务锁CAS实现以及深入误区

          本文链接:https://www.haomeiwen.com/subject/ycxwyxtx.html