• 6.Redis事务(乐观锁)


    事务


    Redis事务的本质:一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中会按照顺序执行!
    一次性、顺序性、排他性

    ---- 队列 set set set  ----
    

    Redis事务没有隔离级别的概念
    所有的命令在事务中没有直接被执行,只有发起执行命令的时候才会执行
    Redis单条式命令保证原子性,但是事务不保证原子性

    redis事务:

    • 开启事务(multi)
    • 命令入队(…)
    • 执行事务(exec)

    锁:Redis可以实现乐观锁

    正常执行事务!

    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
    

    放弃事务

    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)
    
    

    编译型异常:事务中所有命令都不会执行

    27.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> exec
    (error) EXECABORT Transaction discarded because of previous errors.
    127.0.0.1:6379> get k4
    (nil)
    127.0.0.1:6379> get k2
    (nil)
    # 所有的命令都没有执行
    

    运行时异常,事务执行时其他命令正常执行。

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set k1 "v1"
    QUEUED
    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) OK
    2) (error) ERR value is not an integer or out of range # 第一条命令报错但是依旧正常执行
    3) OK
    4) OK
    5) "v3"
    127.0.0.1:6379> get k2
    "v2"
    

    监控! Watch

    悲观锁:

    • 很悲观,认为什么时候都会出问题,无论什么时候都加锁!

    乐观锁:

    • 很乐观,认为什么时候都不会出现问题,所以不会加锁!更新数据时判断在此期间是否有人改动过该数据version
    • 获取version
    • 更新的时候比较version

    正常执行成功

    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> decrby money 20
    QUEUED
    127.0.0.1:6379> incrby out 20
    QUEUED
    127.0.0.1:6379> exec
    1) (integer) 80
    2) (integer) 20
    

    测试多线程修改值后,使用watch可以当作redis的乐观锁操作

    127.0.0.1:6379> watch money
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> decrby money 10
    QUEUED
    127.0.0.1:6379> incrby out 10
    QUEUED
    127.0.0.1:6379> exec # 执行前另外一个线程修改了money的值
    (nil)
    
    127.0.0.1:6379> unwatch # 事务执行失败先解所
    OK
    127.0.0.1:6379> watch money # 再次监视,获取最新的值
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> decrby money 10
    QUEUED
    127.0.0.1:6379> incrby out 10
    QUEUED
    127.0.0.1:6379> exec # 比对监视的值是否发生了变化,如果没有变化则执行成功,如果变化了则执行失败
    1) (integer) 990
    2) (integer) 30
    
    
  • 相关阅读:
    Log4Net使用
    4月博文
    论坛题目练习
    职场冷笑话两则
    初识管理的一些心得
    Project中分清楚挣值项
    预留规划项
    小感触
    好事多磨,好事成双
    忧郁
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13859880.html
Copyright © 2020-2023  润新知