我的编程空间,编程开发者的网络收藏夹
学习永远不晚

乐观锁以及乐观锁的实现

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

乐观锁以及乐观锁的实现

乐观锁以及乐观锁的实现

乐观锁介绍:

乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。那么我们如何实现乐观锁呢,一般来说有以下2种方式:

使用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式。何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据。用下面的一张图来说明:

如上图所示,如果更新操作顺序执行,则数据的版本(version)依次递增,不会产生冲突。但是如果发生有不同的业务操作对同一版本的数据进行修改,那么,先提交的操作(图中B)会把数据version更新为2,当A在B之后提交更新时发现数据的version已经被修改了,那么A的更新操作会失败。

乐观锁定的第二种实现方式和第一种差不多,同样是在需要乐观锁控制的table中增加一个字段,名称无所谓,字段类型使用时间戳(timestamp), 和上面的version类似,也是在更新提交的时候检查当前数据库中数据的时间戳和自己更新前取到的时间戳进行对比,如果一致则OK,否则就是版本冲突。

一、为什么需要锁(并发控制)?
      在多用户环境中,在同一时间可能会有多个用户更新相同的记录,这会产生冲突。这就是著名的并发性问题。
      典型的冲突有:
        1.丢失更新:一个事务的更新覆盖了其它事务的更新结果,就是所谓的更新丢失。例如:用户A把值从6改为2,用户B把值从2改为6,则用户A丢失了他的更新。
        2.脏读:当一个事务读取其它完成一半事务的记录时,就会发生脏读取。例如:用户A,B看到的值都是6,用户B把值改为2,用户A读到的值仍为6。

       为了解决这些并发带来的问题。 我们需要引入并发控制机制。

二、 并发控制机制

             锁,即给我们选定的目标数据上锁,使其无法被其他程序修改。

            1.悲观锁:指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态
            2.乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。乐观锁不能解决脏读的问题。

三、乐观锁的实现
        使用数据版本(Version)记录机制实现,这是乐观锁最常用的一种实现方式。何谓数据版本?即为数据增加一个版本标识,一般是通过为数据库表增加一个数字类型的 “version” 字段来实现。当读取数据时,将version字段的值一同读出,数据每更新一次,对此version值加一。当我们提交更新的时候,判断数据库表对应记录的当前版本信息与第一次取出来的version值进行比对,如果数据库表当前版本号与第一次取出来的version值相等,则予以更新,否则认为是过期数据

   1.数据库表设计

     task

   有三个字段,分别是id,value、version

   2.实现

   1)先读task表的数据(实际上这个表只有一条记录),得到version的值为versionValue

   2)每次更新task表中的value字段时,为了防止发生冲突,需要这样操作

      update task set value = newValue,version =  versionValue + 1   where version = versionValue;

      只有这条语句执行了,才表明本次更新value字段的值成功

如假设有两个节点A和B都要更新task表中的value字段值,差不多在同一时刻,A节点和B节点从task表中读到的version值为2,那么A节点和B节点在更新value字段值的时候,都操作 update task set value = newValue,version =  3   where version = 2;,实际上只有1个节点执行该SQL语句成功,假设A节点执行成功,那么此时task表的version字段的值是3,B节点再操作update task set value = newValue,version =  3   where version = 2;这条SQL语句是不执行的,这样就保证了更新task表时不发生冲突

四、项目中使用案例

    
    @Override
    public int updateForLockNo(BzFinanceEntity editFinance, int queryLockNo) {
 
        editFinance.setLockNo(queryLockNo + 1); //修改乐观锁版本
 
        BzFinanceEntityExample example = new BzFinanceEntityExample();
        BzFinanceEntityExample.Criteria criteria = example.createCriteria();
        criteria.andIdFinanceEqualTo(editFinance.getIdFinance());
        criteria.andLockNoEqualTo(queryLockNo); //基于乐观锁,修改查询版本的数据
        
        //根据Example条件更新实体BzFinanceEntity包含的不是null的属性值
        int mark = this.baseEntityDao.updateByExampleSelective(editFinance, example);
 
        return mark;
    }
 
————————————————
版权声明:本文为CSDN博主「Anyhowe」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sunwenhao_2017/java/article/details/81565783

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

乐观锁以及乐观锁的实现

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

乐观锁以及乐观锁的实现

乐观锁介绍: 乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。那么我们如何
乐观锁以及乐观锁的实现
2016-09-19

mysql悲观锁和乐观锁如何实现

悲观锁是在对数据进行操作之前就先加锁,防止其他事务对数据进行修改,从而确保数据的一致性。在MySQL中,可以通过使用SELECT … FOR UPDATE语句来实现悲观锁。例如:START TRANSACTION;SELECT * FR
mysql悲观锁和乐观锁如何实现
2024-05-08

redis乐观锁与悲观锁的实战

目录概念乐观锁悲观锁乐观锁示例悲观锁示例总结提升概念Redis是一个内存中的键值存储系统,支持多种数据结构,如字符串、哈希、列表等。Redis提供了两种锁机制,即乐观锁和悲观锁。乐观锁乐观锁是一种乐观的并发控制策略,它认为数据在大多数
2023-04-13

MySQL悲观锁与乐观锁如何实现

这篇文章主要为大家展示了“MySQL悲观锁与乐观锁如何实现”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“MySQL悲观锁与乐观锁如何实现”这篇文章吧。前言悲观锁和乐观锁是用来解决并发问题的两种思
2023-06-25

MySQL中的悲观锁与乐观锁

在关系型数据库中,悲观锁与乐观锁是解决资源并发场景的解决方案,接下来将详细讲解一下这两个并发解决方案的实际使用及优缺点。 首先定义一下数据库,做一个最简单的库存表,如下设计:CREATE TABLE `order_stock` (`id`
2022-05-15

mybatis使用乐观锁和悲观锁

悲观锁和乐观锁的概念: 悲观锁:就是独占锁,不管读写都上锁了。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲
2023-08-30

悲观锁与乐观锁怎么利用Hibernate实现

这篇文章将为大家详细讲解有关悲观锁与乐观锁怎么利用Hibernate实现,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。四种隔离机制不要忘记:(1,2,4,8)1.read-uncommitt
2023-05-31

编程热搜

目录