mysql 并发下数据不一致的问题分析及解决
MySQL 5.6 , InnoDB存储引擎,默认事务隔离级别(REPEATABLE-READ)
初始sql 脚本如下:
CREATE DEFINER=`root`@`localhost` PROCEDURE `Test`(out debitb decimal(14,2))
BEGIN
START TRANSACTION ;
select @db:=debit_balance from c_account_customer where id=1 ;
set debitb=@db;
insert into abacus.testvalue (val) values (@db);
update abacus.c_account_customer set debit_balance=@db+1 where id=1;
commit;
END
如上,存储过程中开启事务,先查询debit_balance,查询结果插入testvalue数据表,然后更新debit_balance(加1)
100个并发操作
客户端,同时开启一百个线程,每个线程都调用存储过程Test。
假设数据表c_account_customer中的字段debit_balance初始值为10000.
那么客户端程序执行完成后,理想情况下debit_balance=100、testvalue 数据表有100数据,val值为0-100。
看看结果:
如上,数据未达到预期的原因是在某一时刻,事务A读取debit_balance值时并未锁住数据,事务B(或许更多事务)此时也读到了相同的值,
那么这些事务总体只对debit_balance进行了加1操作。那么如何解决以上问题?即当一个事务读取数据时,锁住数据行,在提交之前,其他事务不能执行。
mysql :select ... for update
修改sql脚本:
CREATE DEFINER=`root`@`localhost` PROCEDURE `Test`(out debitb decimal(14,2))
BEGIN
START TRANSACTION ;
select @db:=debit_balance from c_account_customer where id=1 for update;
set debitb=@db;
insert into abacus.testvalue (val) values (@db);
update abacus.c_account_customer set debit_balance=@db+1 where id=1;
commit;
END
如上,在查询语句后面加上 for update
首先我们来看看并发操作后的结果:
通过图例,我们发现在查询语句中加入for update 解决了上面存在的问题。即我们在查询出debit_balance后就把当前的数据锁定,直到我们修改完毕后再解锁.
现在我们来看看 for update:
在事务中,SELECT ... FOR UPDATE 同一笔数据时会等待其它事务结束后才执行,一般SELECT ... 则不受此影响拿上面的实例来说,当我执行select debit_balance from c_account_customer where id=1 for update;后。我在另外的事务中如果再次执行select debit_balance from c_account_customer where id=1 for update;则第二个事务会一直等待第一个事务的提交,此时第二个查询处于阻塞的状态,但是如果我是在第二个事务中执行select debit_balance from c_account_customer where id=1;则能正常查询出数据,不会受第一个事务的影响 (经过测试)。
补充:MySQL select…for update的Row Lock与Table Lock
上面我们提到,使用select…for update会把数据给锁住,不过我们需要注意一些锁的级别,MySQL InnoDB默认Row-Level Lock,所以只有「明确」地指定主键,MySQL 才会执行Row lock (只锁住被选取的数据) ,否则MySQL 将会执行Table Lock (将整个数据表单给锁住)。
mysql 并发下数据不一致的问题分析及解决的更多相关文章
- Mysql update后insert造成死锁原因分析及解决
系统中出现死锁的日志如下: ) TRANSACTION: , ACTIVE sec inserting mysql tables , locked LOCK WAIT lock struct(s), ...
- C# 关于爬取网站数据遇到csrf-token的分析与解决
需求 某航空公司物流单信息查询,是一个post请求.通过后台模拟POST HTTP请求发现无法获取页面数据,通过查看航空公司网站后,发现网站使用避免CSRF攻击机制,直接发挥40X错误. 关于CSRF ...
- redis作为mysql的缓存服务器(读写分离,通过mysql触发器实现数据同步)
一.redis简介Redis是一个key-value存储系统.和Memcached类似,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录 ...
- MySQL主从复制数据不一致问题【自增主键】
前言: 今天遇到主从表不一致的情况,很奇怪为什么会出现不一致的情况,因为复制状态一直都是正常的.最后检查出现不一致的数据都是主键,原来是当时初始化数据的时候导致的.现在分析记录下这个问题,避免以后再遇 ...
- MySQL多字节字符集造成主从数据不一致问题
MySQL多字节字符集造成主从数据不一致问题 来自江羽 2013-04-27 16:03:56| 分类: 默认分类|举报|字号 订阅 转载: http://backend.blog.163.co ...
- pt-osc改表导致数据不一致案例分析
2016-06-10 李丹 dba流浪猫 我们平时除了解决自己问题外,有时候也会协助圈内人士,进行一些故障排查,此案例就是帮某公司DBA进行的故障分析,因为比较典型,特分享一下,但仅仅是分享发生的过程 ...
- mysql 主从 数据不一致
用pt-table-checksum校验数据一致性 Jun 4th, 2013 主从数据的一致性校验是个头疼的问题,偶尔被业务投诉主从数据不一致,或者几个从库之间的 数据不一致,这会令人沮丧.通常我们 ...
- mysql]一次主从数据不一致的问题解决过程()
问题 要解决问题就是怎么对比不一致,然后在不影响业务的情况下,修复数据不一致的问题,把从库缺少的数据补上 下面是能想到和找到的几个方案 1 从新从0开始同步,虽然对主库的使用没有影响,但是那么大的数据 ...
- [mysql]一次主从数据不一致的问题解决过程
之前一篇: 主从更换ip之后重新建立同步 情况时这样的 昨天晚上主动2个机器都迁移了,然后今天才把主动重新连接上,但是从库的偏移量是从今天当前时刻开始的,也就是说虽然现在主动看似正常,其实是少了昨天的 ...
随机推荐
- python中argparse库的使用教程链接
这两篇文章详细介绍了argparse库的参数设置及使用包括位置参数与可选参数的用法 http://blog.csdn.net/guojuxia/article/details/44462381 htt ...
- Java学习个人备忘录之异常
概述 异常:是在运行时期发生的不正常情况. 在java中用类的形式对不正常情况进行了描述和封装对象. 描述不正常的情况的类,就称为异常类. 以前正常流程代码和问题处理代码相结合,现在将正常流程代码和问 ...
- 原生js移动端可拖动进度条插件
该插件最初的想法来自网上的一篇文章,直达链接:https://www.cnblogs.com/libin-1/p/6220056.html 笔者因为业务需要寻找到这个插件,然后拿来用之,发现各种不方便 ...
- git工具SourceTree工作流
分支模型 master 用来最终上线的分支,最终发布版本,整个项目中有且只有一个 develop 项目中用来开发的分支,原则上项目中有且只有一个,develop 分支下面的分支是经常变化的,会创建新的 ...
- COM 自动化控制Excel应用程序
class Program { static void Main(string[] args) { var dt = new System.Data.DataTable(); dt.Columns.A ...
- HTML5 iframe sandbox javascript getTime
1 1 HTML5 iframe sandbox 1 1 <!DOCTYPE html> <html> <body> <iframe src="de ...
- jCanvaScript canvas的操作库
在jcscript.com上下载最新的jCanvaScript.1.5.18.min.js文件 里面有很多关于canvas的方法都已经是封装好了的,只需直接调用,但是要注意调用之前和调用之后都要写: ...
- MATLAB中mat2gray的用法【转】
函数简介 函数功能:实现图像矩阵的归一化操作.所谓"归一化"就是使矩阵的每个元素的值都在0和1之间.该函数在数字图像处理中经常用到. 调用格式: I = mat2gray(A, [ ...
- 【题解】SHOI2014概率充电器
首先发现答案就是每个节点有电的概率之和.有电的概率牵扯太广不好求,所以转化为求没有电的概率.这题最难的部分在于:一个节点如果有电,可以来自儿子,也可以来自父亲.我们考虑将这两个部分分离开来:建立状态 ...
- [LOJ #2473] [九省联考2018] 秘密袭击coat
题目链接 洛谷. LOJ,LOJ机子是真的快 Solution 我直接上暴力了...\(O(n^2k)\)洛谷要\(O2\)才能过...loj平均单点一秒... 直接枚举每个点为第\(k\)大的点,然 ...