Mysql悲观锁和乐观锁的使用示例
悲观锁
悲观锁,认为数据是悲观的。当我们查询数据的时候加上锁。防止其他线程篡改,直到对方拿到锁,才能修改。
比如,有如下的表。status=1表示可以下单,status=2表示不可以下订单。假如在并发的过程中有两个用户同时查到status=1,那么从逻辑上来说都可以去新增订单,但是会造成商品超卖。
如下例子
CREATETABLE`goods`( `id`int(11)NOTNULLAUTO_INCREMENT, `name`varchar(255)DEFAULTNULL, `status`tinyint(4)DEFAULTNULL, `version`int(11)DEFAULTNULL, PRIMARYKEY(`id`) )ENGINE=InnoDBAUTO_INCREMENT=2DEFAULTCHARSET=utf8mb4 INSERTINTOdemo.goods(id,name,status,version)VALUES(1,'test',1,1);
session1执行
setautocommit=0; begin; select* fromgoodswhereid=1andgoods.status=1forupdate; updategoodssetstatus=2whereid=1;
session2执行
begin; select*fromgoodswhereid=1forupdate;
这时候session2是阻塞的,因为锁还在session1,所以锁一直在等待。如果session1一直不提交,那么session2将在一定时间后超时断开连接,并且报
(1205,‘Lockwaittimeoutexceeded;tryrestartingtransaction')错误,
具体的锁等待时间可以通过设置innodb_lock_wait_timeout参数进行控制。
如果此时在session1中执行commit操作,那么session2将得到查询结果,并把锁交给session2。
我们还可以通过
showstatuslike'innodb_row_lock_%';
来进一步查看锁信息。
乐观锁
乐观锁不同于悲观锁,乐观锁是通过自身的程序实现,而不是mySql自身实现。
乐观锁查询的时不上锁,只有在更新的时候检查版本号。
比如我们查询到goods表中version为1那么在更新这个表的时候Sql将是
select*fromgoodswhereid=1; updategoodssetstatus=2,version=version+1whereid=1andversion=1;
这里的version是查询时候的版本号,每次更改将会导致version+1。如果版本号不匹配更新将不成功。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。