• Redis从0到精通事务


    事务

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

    一次性、顺序性、排他性!执行一些列的命令!

    ------ 队列 set set set 执行------
    

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

    redis的事务:

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

    正常执行事务!

    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
    
    

    放弃事务!(DISCARD )

    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)
    

    编译型异常(代码有问题! 命令有错!) ,事务中所有的命令都不会被执行!

    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/0), 如果事务队列中存在语法性,那么执行命令的时候,其他命令是可以正常执行 的,错误命令抛出异常!

    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"
    
    

    监控! Watch (面试常问!)

    悲观锁:

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

    乐观锁:

    • 很乐观,认为什么时候都不会出问题,所以不会上锁! - - 更新数据的时候去判断一下,在此期间是否 有人修改过这个数据,
    • 获取version
    • 更新的时候比较 version

    Redis测监视测试

    正常执行成功

    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 # 监视 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 # 执行之前,另外一个线程,修改了我们的值,这个时候,就会导致事务执行失
    败!
    (nil)
    
    

    如果修改失败,获取最新的值就好

    image.png

  • 相关阅读:
    软件工程第三次作业
    软件工程第二次作业
    Java基础篇
    2018软件工程第一次作业
    网络基础知识(http请求)
    linux命令
    添加电子称程序
    多线程Demo
    关闭一个winform窗体刷新另外一个
    通过WebApi取出XML数据
  • 原文地址:https://www.cnblogs.com/qq3245792286/p/15405676.html
Copyright © 2020-2023  润新知