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

    课程学习地址:
    https://www.bilibili.com/video/BV1S54y1R7SB?p=23
    中间手册地址:
    http://www.redis.cn/

    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
    

    放弃事务

    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> discard # 取消事务
    OK
    127.0.0.1:6379> get k2 #事务中的队列命令都不会被执行
    (nil)
    

    异常

    编译型异常(代码有问题1!命令有错!)

    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)
    127.0.0.1:6379> get k1
    (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 对象 (获取money的值)
    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 # 1.如果发现事务执行失败,就先解锁
    127.0.0.1:6379> watch money # 2.监视money对象 (获取money最新的值,再次监视,select version)
    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 # 3.执行之前,比较监视的值是否发生了变化,如果没有变化,那么可以执行成功,否帽就会导致事务执行失败!
    1)(integer) 999
    2)(integer) 1000
    
  • 相关阅读:
    mysqlslap
    Linux操作手册
    Linux操作手册
    Linux编程手册
    一篇文章搞懂CGlib动态代理
    (超详细!)彻底搞懂动态代理和静态代理
    (新手教学)IDEA快速搭建Spring
    十分钟彻底搞懂Java反射
    (面试题)如何之字形打印二维数组
    相同文件夹中其他jsp页面可以访问,但是个别访问不了
  • 原文地址:https://www.cnblogs.com/haima/p/13764036.html
Copyright © 2011-2022 走看看