在开发中遇到过这样一个问题
一个看视频记录,更新到100就表示看完了,后面再有请求不继续更新了.
结果是:
导致,里面很多数据出现问题.
推测是以下的情况才会导致
第一条请求 事务在执行中,还未提交(因为本地有时候比较难再现,于是手动在程序中,第一条记录处理的时候,sleep了几秒,就达到这种效果了)
第二条请求 事务已经开始执行,这个时候查到的历史最大值不是100,才会去进行了更新
网上看了一下解决方案:
悲观锁
直接锁行记录
这个我在本地测试,确实有效,一个事务开始没结束,第二个事务一个等待,不过会导致处于阻塞状态,因为系统并发,不敢考虑,也就是记录下这个方式.
手动模拟:
执行第一个事务:
-- 视频100BEGIN; SELECT * FROM `biz_coursestudyhistory` WHERE sid = 5777166; UPDATE biz_coursestudyhistory set studyStatus = 100,versionNO=versionNO+1 WHERE sid = 1 AND versionNO = 0; -- commit ; 先不执行,先注解掉,只执行上面的
接着执行第二个事务:
BEGIN; UPDATE biz_coursestudyhistory set studyStatus = 90,versionNO=versionNO+1 WHERE sid = 1 AND versionNO = 0; SELECT * FROM `biz_coursestudyhistory` WHERE sid = 1 FOR UPDATE; COMMIT;
会发现成功不了,一直处于等待状态.
查看锁
确实被锁住了,这里只要执行第一个事务的commit ,第二个事务就会执行.
从这里可以看出,行锁可以直接达到理想的数据统一状态,一个事务修改,其他都不能操作,感觉这种比较适合银行这种安全性的项目
乐观锁:
这种比较简单,并且不会造成阻塞
方式就是加上版本号
var maxver = select max(version) from table
更新的话使用
update table set studystatus = xxx,version = version +1 where id =1 and version = maxver
写入的话
INSERT into table (contentStudyID,courseWareID,studyStatus,studyTime,endTime) SELECT 27047358,3163,100,333,NOW() FROM dual WHERE NOT EXISTS (SELECT 1 FROM table WHERE contentStudyID =27047358 AND courseWareID = 3163 )
这种方式,可以在更新或者写入的时候,直接判断库里面存在的数据是否存在,如果不存在则是别其他的线程使用了.
修改为这种写法后,使用jmeter进行多线程测试,从最开始的多条记录更新成功,变成只有一个成功,后面的失败.
从最开始的插入多条记录,到后来的只能插入一条数据了
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
Mysql,事务,并发问题,解决
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。