mybatis乐观锁实现,解决并发问题
银行两操作员同时操作同一账户就是典型的例子。
比如A、B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户扣除50元,A先提交,B后提交。最后实际账户余额为1000-50=950元,但本该为1000+100-50=1050。这就是典型的并发问题。
乐观锁机制在一定程度上解决了这个问题。乐观锁,大多是基于数据版本(Version)记录机制实现。何谓数据版本?即为数据增加一个版本标识,在基于数据库表的版本解决方案中,一般是通过为数据库表增加一个 “version” 字段来实现。
读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。
对于上面修改用户帐户信息的例子而言,假设数据库中帐户信息表中有一个version字段,当前值为1;而当前帐户余额字段(balance)为1000元。假设操作员A先更新完,操作员B后更新。
a、操作员A此时将其读出(version=1),并从其帐户余额中增加100(1000+100=1100)。
b、在操作员A操作的过程中,操作员B也读入此用户信息(version=1),并从其帐户余额中扣除50(1000-50=950)。
c、操作员A完成了修改工作,将数据版本号加一(version=2),连同帐户增加后余额(balance=1100),提交至数据库更新,此时由于提交数据版本大于数据库记录当前版本,数据被更新,数据库记录version更新为2。
d、操作员B完成了操作,也将版本号加一(version=2)试图向数据库提交数据(balance=950),但此时比对数据库记录版本时发现,操作员B提交的数据版本号为2,数据库记录当前版本也为2,不满足 “提交版本必须大于记录当前版本才能执行更新 “的乐观锁策略,因此,操作员B的提交被驳回。
这样,就避免了操作员B用基于version=1的旧数据修改的结果覆盖操作员A的操作结果的可能。
操作员A操作如下:
select id, balance, version from account where id="1";
查询结果:id=1, balance=1000, version=1 update account
set balance=balance+100, version=version+1
where id="1" and version=1 select id, balance, version from account where id="1";
查询结果:id=1, balance=1100, version=2
操作员B操作如下:
select id, balance, version from account where id="1";
查询结果:id=1, balance=1000, version=1 #操作员A已修改成功,实际account.balance=1100、account.version=2,操作员B也将版本号加一(version=2)试图向数据库提交数据(balance=950),但此时比对数据库记录版本时发现,操作员B提交的数据版本号为2,数据库记录当前版本也为2,不满足 “提交版本必须大于记录当前版本才能执行更新 “的乐观锁策略,因此,操作员B的提交被驳回。
update account
set balance=balance-50, version=version+1
where id="1" and version=1 select id, balance, version from account where id="1";
查询结果:id=1, balance=1100, version=2
Hibernate、JPA等ORM框架或者实现,是使用版本号,再判断UPDATE后返回的数值
mybatis乐观锁实现,解决并发问题的更多相关文章
- mybatis 乐观锁和逻辑删除
本篇介绍easymybatis如配置乐观锁和逻辑删除. 乐观锁 easymybatis提供的乐观锁使用方式跟JPA一样,使用@Version注解来实现.即:数据库增加一个int或long类型字段ver ...
- mybatis基本流程、jdbc连接、ps:附mybatis(乐观锁)实现
一.前言 Mybatis和Hibernate一样,是一个优秀的持久层框架.已经说过很多次了,原生的jdbc操作存在大量的重复性代码(如注册驱动,创建连接,创建statement,结果集检测等).框架的 ...
- 乐观锁机制解决多层嵌套异步ajax问题
前言 在项目中我们通常需要使用ajax异步嵌套去请求数据并做数据的展示,当我们多次快速的多次的发起ajax,因为ajax是异步的,每个ajax触发回调的时间都是不可控的,这样就会造成前面发起的ajax ...
- 十三: 悲观锁&乐观锁:解决丢失更新问题
悲观锁:认为丢失更新一定会出现,可以在查询的时候加入for update 认为丢失更新一定会出现,查询时: select * from account for update;for update : ...
- SQL锁表解决并发性
在数据库开发过程中,不得不考虑并发性的问题,因为很有可能当别人正在更新表中记录时,你又从该表中读数据,那你读出来的数据有可能就不是你希望得到的数据.可以说有些数据同时只能有一个事物去更新,否则最终显示 ...
- PHP.39-扩展-锁机制解决并发-MySQL锁、PHP文件锁
锁机制适用于高并发场景:高并发订单.秒杀…… apache压力测试 Mysql锁详解 语法 加锁:LOCK TABLE 表名1 READ|WRITE, 表名2 READ|WRITE ......... ...
- 【mybatis-plus】什么是乐观锁?如何实现“乐观锁”
"乐观锁"这个词以前我也没听过.上次在测试需求的时候,查询数据库发现有一个version字段,于是请教开发这个字干嘛使, 人家回复我:乐观锁,解决并发更新用的.当时大家都忙,咱也不 ...
- sql server对并发的处理-乐观锁和悲观锁【粘】
假如两个线程同时修改数据库同一条记录,就会导致后一条记录覆盖前一条,从而引发一些问题. 例如: 一个售票系统有一个余票数,客户端每调用一次出票方法,余票数就减一. 情景: 总共300张票,假设两个售票 ...
- sql server对并发的处理-乐观锁和悲观锁
https://www.cnblogs.com/dengshaojun/p/3955826.html sql server对并发的处理-乐观锁和悲观锁 假如两个线程同时修改数据库同一条记录,就会导致后 ...
随机推荐
- wamp密码设置
WAMP安装好后,mysql密码是为空的,那么要如何修改呢?其实很简单,通过几条指令就行了,下面我就一步步来操作. 首先,通过WAMP打开mysql控制台. 提示输入密码,因为现在是空,所以直接按回车 ...
- pip使用
安装指定版本的插件: pip install -v matplotlib==1.5.1 #安装matplotlib version 1.5.1
- 友盟分享SDK集成步骤
1.官方注册appID. 2.menifest添加和声明umeng相关的activity以及appKey. 3. // 首先声明一个controller变量,由友盟服务工厂类直接取得友盟社交服务. m ...
- 2016---ios面试题
1.对数组中的元素去重复 例如: 1 2 3 NSArray *array = @[@"12-11", @"12-11", @"12-11&q ...
- 安装 composer SSL operation failed with code 1
gavin@webdev:~> curl -sS https://getcomposer.org/installer | php Downloading... Download failed: ...
- markdown编辑器实现笔记
1.js代码放在head和body的区别 <html> <head> <script src="https://cdnjs.cloudflare.com/aja ...
- javascript学习第二课
主要内容: 1.不可变的原始值和可变的对象引用 javascript中的原始值(undefined.null.布尔值.数字和字符串)与对象(包括数组和函数)有着根本的区别.原始值是不可更改的;任何方法 ...
- OpenWRT连接OPENVPN的教程
这是相当基本没有任何web界面,只是几个命令如何运行OpenWRT的 OpenVPN的例子. OpenWRT的设置更复杂,所以这个教程仅供爱好者和经验的用户使用参考. 本教程假定您有OpenWRT的安 ...
- 【Java】XML解析之JDOM
JDOM介绍 JDOM是一个开源项目,它基于树型结构,利用纯JAVA的技术对XML文档实现解析.生成.序列化以及多种操作.使用jdom需要引入jdom.jar包. XML生成及解析 代码如下: pac ...
- 修改默认MYSQL数据库data存放位置
随着业务量的增长,mysql默认安装所在分区大小出现瓶颈,通常需要将datadir换到较大的分区 示例原目录:/usr/local/mysql/data/示例新目录:/data/mysqldata/ ...