mysql悲观锁总结和实践
使用场景举例:以MySQL InnoDB为例
商品t_goods表中有一个字段status,status为1代表商品未被下单,status为2代表商品已经被下单,那么我们对某个商品下单时必须确保该商品status为1。假设商品的id为1。
一、如果不采用锁,那么操作方法如下:
//1.查询出商品信息
select status from t_goods where id=1;
//2.根据商品信息生成订单
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status为2
update t_goods set status=2 where id=1;
上面这种场景在高并发访问的情况下很可能会出现问题。
前面已经提到,只有当goods status为1时才能对该商品下单,上面第一步操作中,查询出来的商品status为1。但是当我们执行第三步Update操作的时候,有可能出现其他人先一步对商品下单把goods status修改为2了,但是我们并不知道数据已经被修改了,这样就可能造成同一个商品被下单2次,使得数据不一致。所以说这种方式是不安全的。
二、使用悲观锁来实现:
在上面的场景中,商品信息从查询出来到修改,中间有一个处理订单的过程,使用悲观锁的原理就是,当我们在查询出goods信息后就把当前的数据锁定,直到我们修改完毕后再解锁。那么在这个过程中,因为goods被锁定了,就不会出现有第三者来对其进行修改了。
注:要使用悲观锁,我们必须关闭mysql数据库的自动提交属性,因为MySQL默认使用autocommit模式,也就是说,当你执行一个更新操作后,MySQL会立刻将结果进行提交。
我们可以使用命令设置MySQL为非autocommit模式:
set autocommit=0;
设置完autocommit后,我们就可以执行我们的正常业务了。具体如下:
//0.开始事务
begin;/begin work;/start transaction; (三者选一就可以)
//1.查询出商品信息
select status from t_goods where id=1 for update;
//2.根据商品信息生成订单
insert into t_orders (id,goods_id) values (null,1);
//3.修改商品status为2
update t_goods set status=2 where id=1;
//4.提交事务
commit;/commit work;
注:上面的begin/commit为事务的开始和结束,因为在前一步我们关闭了mysql的autocommit,所以需要手动控制事务的提交,在这里就不细表了。
上面的第一步我们执行了一次查询操作:select status from t_goods where id=1 for update;
与普通查询不一样的是,我们使用了select…for update的方式,这样就通过数据库实现了悲观锁。此时在t_goods表中,id为1的那条数据就被我们锁定了,其它的事务必须等本次事务提交之后才能执行。这样我们可以保证当前的数据不会被其它事务修改。
注:需要注意的是,在事务中,只有SELECT ... FOR UPDATE 或LOCK IN SHARE MODE 同一笔数据时会等待其它事务结束后才执行,一般SELECT ... 则不受此影响。拿上面的实例来说,当我执行select status from t_goods where id=1 for update;后。我在另外的事务中如果再次执行select status from t_goods where id=1 for update;则第二个事务会一直等待第一个事务的提交,此时第二个查询处于阻塞的状态,但是如果我是在第二个事务中执行select status from t_goods 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悲观锁总结和实践》乐观锁
mysql乐观锁总结和实践 博客分类: MyBatis 数据库 mysql数据库乐观锁悲观锁 上一篇文章<MySQL悲观锁总结和实践>谈到了MySQL悲观锁,但是悲观锁并不是适用于任何场景 ...
- MySql悲观锁总结与实践
mysql(for update)悲观锁总结与实践 https://blog.csdn.net/zmx729618/article/details/52701972 悲观锁,正如其名,它指的是对数据被 ...
- mysql悲观锁总结和实践--转
原文地址:http://chenzhou123520.iteye.com/blog/1860954 最近学习了一下数据库的悲观锁和乐观锁,根据自己的理解和网上参考资料总结如下: 悲观锁介绍(百科): ...
- 《mysql悲观锁总结和实践》-悲观锁
最近学习了一下数据库的悲观锁和乐观锁,根据自己的理解和网上参考资料总结如下: 悲观锁介绍(百科): 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持 ...
- mysql乐观锁总结和实践--转
原文地址:http://chenzhou123520.iteye.com/blog/1863407 上一篇文章<MySQL悲观锁总结和实践>谈到了MySQL悲观锁,但是悲观锁并不是适用于任 ...
- mysql乐观锁总结和实践(二)
一篇文章<MySQL悲观锁总结和实践>谈到了MySQL悲观锁,但是悲观锁并不是适用于任何场景,它也有它存在的一些不足,因为悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占 ...
- mysql乐观锁总结和实践(转)
原文:mysql乐观锁总结和实践 上一篇文章<MySQL悲观锁总结和实践>谈到了MySQL悲观锁,但是悲观锁并不是适用于任何场景,它也有它存在的一些不足,因为悲观锁大多数情况下依靠数据库的 ...
- 【MySQL】MySQL悲观锁 + 事物 + for update 解决普通流量并发的问题
使用mysql悲观锁解决并发问题 最近学习了一下数据库的悲观锁和乐观锁,根据自己的理解和网上参考资料总结如下: 悲观锁介绍(百科): 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事 ...
- mysql悲观锁处理赠品库存超卖的情况
处理库存超卖的情况前,先了解下什么是乐观锁和悲观锁,下面的几篇博客已经介绍的比较详细了,我就不在赘述其原理了 [MySQL]悲观锁&乐观锁 对mysql乐观锁.悲观锁.共享锁.排它锁.行锁.表 ...
随机推荐
- hello
#include <iostream> int main() { std::cout << "请输入两个数字:" << std::endl; , ...
- jsp学习---css基础知识学习,float,position,padding,div,margin
1.常用页面布局 效果图: 代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...
- LINK : fatal error LNK1104: 无法打开文件“gtestd.lib”
解决办法: 复制编译出来的gtestd.lib文件到D:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib目录下 我这里用的是vs2015 ...
- mysql死锁问题解决步骤
锁表产生的原因 锁表的具体情况 解决锁表问题 1.查询是否锁表 show OPEN TABLES where In_use > 0; 2.查询进程 show processlist; 查询到相对 ...
- 利用Lambda获取属性名称
感谢下面这篇博文给我的思路: http://www.cnblogs.com/daimage/archive/2012/04/10/2440186.html 上面文章的博主给出的代码是可用的,但是调用方 ...
- 彻底卸载sublime txt
最近彻底重装系统之后,安装sublime txt3, 自己设置了一些,总是觉得不是很对劲,想重新安装. 结果每次安装之后,总是有一些配置文件和卸载之前的是一样的,重复几次总是如此,于是网上搜资料,怎么 ...
- Sql Server 复制表
SELECT INTO 和 INSERT INTO SELECT 两种表复制语句 1.INSERT INTO SELECT语句 语句形式为:Insert into Table2(field1,fiel ...
- Points on cycle
Description There is a cycle with its center on the origin. Now give you a point on the cycle, you a ...
- [Chapter 3 Process]Practice 3.12 Including the initial parent process, how many processes are created by the program shown in Figure 3.32?
3.12 Including the initial parent process, how many processes are created by the program shown in Fi ...
- homework 11 2016 5 13 读入文件做输入
#include <iostream>#include <fstream> using namespace std; int main(){ string x, y, z; c ...