博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于ORACLE的乐观锁实现原理
阅读量:6160 次
发布时间:2019-06-21

本文共 1034 字,大约阅读时间需要 3 分钟。

hot3.png

  由于oracle的update、delete等DML语句是单线程的,具有天生的线程安全性。所以我们可以利用DML语句进行大并发环境下数据准确性、一致性控制。

  先来看一下oracle的DML行锁现象,当表中某一条记录正在执行DML操作时,oracle会为该条记录增加行锁,其他线程过来操作时,需等待第一个线程先执行完毕。如下图所示:

220430_I4Wj_2994921.png

第一个会话未提交

220208_B9a3_2994921.png

 

第二个会话进入等待状态

220308_55cs_2994921.png

    我们一步步看一下oracle的执行过程

1、当第一个update执行完毕,并提交后,数据库的结果如下:

SQL:

update test2 a set a.status_cd='11',a.version_lock=a.version_lock+1 where a.id=1 and a.version_lock=100;

220608_7axY_2994921.png

 

2、当第二个update执行完毕并提交,数据库的结果如下:

SQL:

update test2 a set a.status_cd='12',a.version_lock=a.version_lock+1 where a.id=1 and a.version_lock=100;

220821_7XyX_2994921.png

 

220907_ExIv_2994921.png

3、经过第一步和第二步后,数据库中ID=1的记录,状态并不等于12????这就是oracle神奇的地方,也是我们在大并发多终端下,保持数据一致性、准确性的重要依据。

   有了以上的理论依据时,我们在mybatis中实现乐观锁的实现思路如下:

1、在数据库表中增加version字段;

2、数据操作之前,先读取表记录中对应的version值,若是集群环境下,多台服务器可能同时会拿到相同的version,此时你也许会担心,version和id都一致,那会不会重复操作某条记录啊?不用担心,继续往下看....

3、当多个线程同时更新某一条记录时,oracle的行锁机制,同时只会让某一个线程来操作这条记录,操作成功后version+1,那么其他线程所持有的version已经是旧的了,当执行update操作时,无法找到对应的记录进行操作;

4、我们可以在程序后根据update执行的结果所对应的行数rows,来判断是否为0,如果是,则说明该条记录已被其他线程操作过了,程序无需进去往下执行,直接跳出即可;

5、以上过程可以封装为mybatis的插件,让插件自动在需要的sql中追加version版本控制;

 

 

 

 

 

 

转载于:https://my.oschina.net/weal666/blog/792546

你可能感兴趣的文章
Dijkstra算法
查看>>
css 动画 和 响应式布局和兼容性
查看>>
csrf 跨站请求伪造相关以及django的中间件
查看>>
MySQL数据类型--与MySQL零距离接触2-11MySQL自动编号
查看>>
生日小助手源码运行的步骤
查看>>
Configuration python CGI in XAMPP in win-7
查看>>
bzoj 5006(洛谷 4547) [THUWC2017]Bipartite 随机二分图——期望DP
查看>>
CF 888E Maximum Subsequence——折半搜索
查看>>
欧几里德算法(辗转相除法)
查看>>
面试题1-----SVM和LR的异同
查看>>
MFC控件的SubclassDlgItem
查看>>
如何避免历史回退到登录页面
查看>>
《图解HTTP》1~53Page Web网络基础 HTTP协议 HTTP报文内的HTTP信息
查看>>
unix环境高级编程-高级IO(2)
查看>>
树莓派是如何免疫 Meltdown 和 Spectre 漏洞的
查看>>
雅虎瓦片地图切片问题
查看>>
HTML 邮件链接,超链接发邮件
查看>>
HDU 5524:Subtrees
查看>>
手机端userAgent
查看>>
pip安装Mysql-python报错EnvironmentError: mysql_config not found
查看>>