【Redis】事务和乐观锁如何实现?

命运对每个人都是一样的,不一样的是各自的努力和付出不同,付出的越多,努力的越多,得到的回报也越多,在你累的时候请看一下身边比你成功却还比你更努力的人,这样,你就会更有动力。

导读:本篇文章讲解 【Redis】事务和乐观锁如何实现?,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

前言

  • 事务

    在Redis事务没有没有隔离级别的概念!
    在Redis单条命令式保证原子性的,但是事务不保证原子性!

    • ①原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。
    • ②一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
    • ③隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
    • ④持久性(durability)。持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
  • 乐观锁

    在Redis是可以实现乐观锁的!

    • ①当程序中可能出现并发的情况时,就需要保证在并发情况下数据的准确性,以此确保当前用户和其他用户一起操作时,所得到的结果和他单独操作时的结果是一样的。
    • ②没有做好并发控制,就可能导致脏读、幻读和不可重复读等问题。

Redis如何实现事务?

由以上可以得出结论,Redis是支持单条命令事务的,但是事务并不能保证原子性!

  • 正常执行事务

    127.0.0.1:6379> multi  #开启事务
    OK
    127.0.0.1:6379> set name dingyongjun  #添加数据
    QUEUED
    127.0.0.1:6379> set age 26  #添加数据
    QUEUED
    127.0.0.1:6379> set high 172  #添加数据
    QUEUED
    127.0.0.1:6379> exec  执行事务
    1) OK
    2) OK
    3) OK
    127.0.0.1:6379> get name  #获取数据成功,证明事务执行成功
    "dingyongjun"
    127.0.0.1:6379> get age
    "26"
  • 放弃事务

    127.0.0.1:6379> multi  #开启事务
    OK
    127.0.0.1:6379> set name dingyongjun  #添加数据
    QUEUED
    127.0.0.1:6379> set age 26  #添加数据
    QUEUED
    127.0.0.1:6379> discard  #放弃事务
    OK
    127.0.0.1:6379> get name  #不会执行事务里面的添加操作
    (nil)
  • 编译时异常,代码有问题,或者命令有问题,所有的命令都不会被执行

    127.0.0.1:6379> multi  #开启事务
    OK
    127.0.0.1:6379> set name dingyongjun  #添加数据
    QUEUED
    127.0.0.1:6379> set age 23  #添加数据
    QUEUED
    127.0.0.1:6379> getset name  #输入一个错误的命令,这时候已经报错了,但是这个还是进入了事务的队列当中
    (error) ERR wrong number of arguments for 'getset' command
    127.0.0.1:6379> set high 173  #添加数据
    QUEUED
    127.0.0.1:6379> exec  #执行事务,报错,并且所有的命令都不会执行
    (error) EXECABORT Transaction discarded because of previous errors.
    127.0.0.1:6379> get name  #获取数据为空,证明没有执行
    (nil)
  • 运行时异常,除了语法错误不会被执行且抛出异常后,其他的正确命令可以正常执行

    127.0.0.1:6379> multi  #开启事务
    OK
    127.0.0.1:6379> set name dingyongjun  #添加字符串数据
    QUEUED
    127.0.0.1:6379> incr name  #对字符串数据进行自增操作
    QUEUED
    127.0.0.1:6379> set age 23  #添加数据
    QUEUED
    127.0.0.1:6379> get age  #获取数据
    QUEUED 
    127.0.0.1:6379> exec  #执行事务。虽然对字符串数据进行自增操作报错了,但是其他的命令还是可以正常执行的
    1) OK
    2) (error) ERR value is not an integer or out of range
    3) OK
    4) "23"
    127.0.0.1:6379> get age  #获取数据成功
    "23"

Redis如何实现乐观锁?

  • watch(监视)

    127.0.0.1:6379> set money 100  #添加金钱100
    OK
    127.0.0.1:6379> set cost 0  #添加花费0
    OK
    127.0.0.1:6379> watch money  #监控金钱
    OK
    127.0.0.1:6379> multi  #开启事务
    OK
    127.0.0.1:6379> DECRBY money 30  #金钱-30
    QUEUED
    127.0.0.1:6379> incrby cost 30  #花费+30
    QUEUED
    127.0.0.1:6379> exec  #执行事务,成功!这时候数据没有发生变动才可以成功
    1) (integer) 70
    2) (integer) 30
  • 多线程测试watch

    #线程1

    #线程1
    127.0.0.1:6379> set money 100  #添加金钱100
    OK
    127.0.0.1:6379> set cost 0  #添加花费0
    OK
    127.0.0.1:6379> watch money  #开启监视(乐观锁)
    OK 
    127.0.0.1:6379> multi  #开启事务
    OK
    127.0.0.1:6379> DECRBY money 20  #金钱-20
    QUEUED
    127.0.0.1:6379> INCRBY cost 20   #花费+20
    QUEUED
    #这里先不要执行,先执行线程2来修改被监视的值
    127.0.0.1:6379> exec  #执行报错,因为我们监视了money这个值,如果事务要对这个值进行操作前
    #监视器会判断这个值是否正常,如果发生改变,事务执行失败!
    (nil)

    #线程2

    #线程2,这个在事务执行前操作执行
    127.0.0.1:6379> INCRBY money 20  #金钱+20
    (integer) 120

悲观锁与乐观锁

  • 悲观锁: 什么时候都会出问题,所以一直监视着,没有执行当前步骤完成前,不让任何线程执行,十分浪费性能!一般不使用!
  • 乐观锁: 只有更新数据的时候去判断一下,在此期间是否有人修改过被监视的这个数据,没有的话正常执行事务,反之执行失败!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/143987.html

(0)

及时掌握行业动态,欢迎加入几百人的后端技术交流群:


相关推荐

  • 【JavaEE】多线程笔记第一天(进程的理解、线程的理解与创建、Thread类、线程状态)

    导读:本篇文章讲解 【JavaEE】多线程笔记第一天(进程的理解、线程的理解与创建、Thread类、线程状态),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

    后端笔记 2023年2月28日
    0031
  • Go语言实现阻塞读且并发安全的Map

    不管现实多么惨不忍睹,都要持之以恒地相信,这只是黎明前短暂的黑暗而已。不要惶恐眼前的难关迈不过去,不要担心此刻的付出没有回报,别再花时间等待天降好运。真诚做人,努力做事!你想要的,岁月都会给你。Go语言实现阻塞读且并发安全的Map,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

    后端笔记 2023年12月11日
    0058
  • Docker使用Jenkins部署项目

    得意时要看淡,失意时要看开。不论得意失意,切莫大意;不论成功失败,切莫止步。志得意满时,需要的是淡然,给自己留一条退路;失意落魄时,需要的是泰然,给自己觅一条出路Docker使用Jenkins部署项目,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

    后端笔记 2023年8月2日
    00224
  • Django执行原生SQL的模糊查询时,百分号(%)替换问题

    导读:本篇文章讲解 Django执行原生SQL的模糊查询时,百分号(%)替换问题,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

    后端笔记 2023年2月27日
    0027
  • 剑指刷题笔记五:替换空格(利用C++语言,将字符串中的空格替换成‘%20’)

    追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

    导读:本篇文章讲解 剑指刷题笔记五:替换空格(利用C++语言,将字符串中的空格替换成‘%20’),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

    后端笔记 2023年4月6日
    0032
  • 用 Pycharm 远程连接 Linux 服务器进行炼丹

    导读:本篇文章讲解 用 Pycharm 远程连接 Linux 服务器进行炼丹,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

    2023年2月26日
    00335
  • 【全局唯一id】分库分表之后,id 主键如何处理?

    人生之路不会是一帆风顺的,我们会遇上顺境,也会遇上逆境,在所有成功路上折磨你的,背后都隐藏着激励你奋发向上的动机,人生没有如果,只有后果与结果,成熟,就是用微笑来面对一切小事。

    导读:本篇文章讲解 【全局唯一id】分库分表之后,id 主键如何处理?,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

    后端笔记 2023年3月8日
    0084
  • 【Shell】初识Shell编程

    命运对每个人都是一样的,不一样的是各自的努力和付出不同,付出的越多,努力的越多,得到的回报也越多,在你累的时候请看一下身边比你成功却还比你更努力的人,这样,你就会更有动力。

    导读:本篇文章讲解 【Shell】初识Shell编程,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

    后端笔记 2023年5月24日
    0030
  • 3D旋转立方体相册

    书读的越多而不加思考,你就会觉得你知道得很多;而当你读书而思考得越多的时候,你就会越清楚地看到,你知道得很少。

    导读:本篇文章讲解 3D旋转立方体相册,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

    后端笔记 2023年3月4日
    0033
  • HashMap源码解读(下篇)

    导读:本篇文章讲解 HashMap源码解读(下篇),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

    2023年2月20日
    0051

发表回复

登录后才能评论