当前位置:网站首页>关于update操作并发问题
关于update操作并发问题
2020-11-07 20:56:00 【daydaydream】
在高并发的场景下,经常会遇到这种情况:
A请求过来,查询出来一条数据,进行update操作,与此同时B请求也在这个时候过来,对这条数据进行查询,并进行操作。此时就会出现B在A之后进行查询操作,但是实际B的数据却被A覆盖。
表名A,字段名为 number,如下的SQL语句:
甲操作 语句1:select num from store where id='1';
假设此时甲获取到 num= 99
乙操作 语句2:select num from store where id='1';
因为甲方还没有update操作,乙获也取到 num= 99
这时候A进行update操作
update store set num =${num} +1 where id='1';
这时候写入数据库的num即为100
此时B请求也发起了更新操作:
update store set num =${num} +1 where id='1';
这时候我们的预期本应该是101的,但是实际上B又在数据库写入了100
解决方案:
(1)引入一个版本号的概念,在表A中增加一个version字段
甲操作 语句1:select num,version from store where id='1';
假设此时甲获取到 num= 99 version =1
乙操作 语句2:select num,version from store where id='1';
因为甲方还没有update操作,乙获也取到 num= 99 version=1
这时候A进行update操作
update store set num =${num} +1 where id='1' and version = ${version};
这时候写入数据库的num即为100, version =2
此时B请求也发起了更新操作:
update store set num =${num} +1 where id='1' and version = ${version} ;
这时候发现条件version = 1不成立,因为上一步操作version已经为2了,所以update无法更新。
(2)解决方式:update A set number=number+1 where id=1; 语句直接处理
表名A,字段名为 number,如下的SQL语句:
语句1:update A set number=number+1 where id=1;
语句2:update A set number=number+2 where id=1;
假设这两条SQL语句同时被mysql执行,id=1的记录中number字段的原始值为99,那么是否有可能出现这种情况:
语句1和2因为同时执行,他们得到的number的值都是99,都是在10的基础上分别加1和2,导致最终number被更新为100或101,而不是102
这个其实就是 关系型数据库本身就需要解决的问题。首先,他们同时被MySQL执行,你的意思其实就是他们是并发执行的,而并发执行的事务在关系型数据库中是有专门的理论支持的- ACID,事务并行等理论,所有关系型数据库实现,包括Oracle, MySQL都需要遵循这个原理。
简单一点理解就是锁的原理。这个时候第一个update会持有id=1这行记录的 排它锁,第二个update需要持有这个记录的排它锁的才能对他进行修改,正常的话, 第二个update会阻塞,直到第一个update提交成功,他才会获得这个锁,从而对数据进行修改。
也就是说,按照关系型数据库的理论,这两个update都成功的话,id=1的number一定会被修改成22。如果不是22, 那就是数据库实现的一个严重的bug。
版权声明
本文为[daydaydream]所创,转载请带上原文链接,感谢
https://blog.51cto.com/13238147/2547477
边栏推荐
- Do not understand the underlying principle of database index? That's because you don't have a B tree in your heart
- The official 1909 version of win10 cannot open the real-time protection solution of virus and threat protection in windows security center.
- 留给快手的时间不多了
- 如何以计算机的方式去思考
- 模型预测准确率高达94%!利用机器学习完美解决2000亿美元库存难题
- 我们为什么需要软件工程——从一个简单的项目进行观察
- 屏读时代,我们患上了注意力缺失候群症
- Didi's distributed ID generator (tinyid), easy to use
- Business facade and business rule
- 来自不同行业领域的50多个对象检测数据集
猜你喜欢
[C + + learning notes] how about the simple use of the C + + standard library STD:: thread?
A detailed explanation of microservice architecture
Didi's distributed ID generator (tinyid), easy to use
Mac新手必备小技巧
The samesite problem of cross domain cookie of Chrome browser results in abnormal access to iframe embedded pages
利用线程通信、解决缓存穿透数据库雪崩
洞察——风格注意力网络(SANet)在任意风格迁移中的应用
Reflection on a case of bus card being stolen and swiped
chrome浏览器跨域Cookie的SameSite问题导致访问iframe内嵌页面异常
工作1-3年的程序员,应该具备怎么样的技术能力?该如何提升?
随机推荐
Didi's distributed ID generator (tinyid), easy to use
[original] the influence of arm platform memory and cache on the real-time performance of xenomai
awk实现类sql的join操作
GrowingIO 响应式编程探索和实践
In simple terms, the large front-end framework angular6 practical course (angular6 node.js 、keystonejs、
laravel8更新之维护模式改进
Implementation of Caesar cipher
高级并发编程系列九(Lock接口分析)
AC86U kx上网
Mac新手必备小技巧
Insight -- the application of sanet in arbitrary style transfer
在 Amazon SageMaker 管道模式下使用 Horovod 实现多 GPU 分布式训练
Three steps, one pit, five steps and one thunder, how to lead the technical team under the rapid growth?
Exploration and practice of growingio responsive programming
使用 Xunit.DependencyInjection 改造测试项目
一次公交卡被“盜刷”事件帶來的思考
Stack bracket matching
Business facade and business rule
洞察——风格注意力网络(SANet)在任意风格迁移中的应用
DOM node operation