laravel框架中使用mysql排他锁代码示例及场景介绍
Laravel  /  管理员 发布于 2年前   952
mysql中的排他锁(EXclusive Lock),又称X锁、独占锁、写锁,针对行锁。
当有事务对数据加写锁后,其他事务不能再对锁定的数据加任何锁,又因为InnoDB对select语句默认不加锁,所以其他事务除了不能写操作外,照样是允许读的(尽管不允许加读锁)。
使用需求描述:
当mysql数据库的某条记录被多个php进程同时修改时,希望数据修改正确。
示例表 - user表
用来测试排他锁,实现通过加锁与解锁
创建用户表
CREATE TABLE users (
id int(11) NOT NULL AUTO_INCREMENT,
user_name varchar(255) NOT NULL DEFAULT '' comment '用户名称',
level tinyint not null default 0 comment '用户类别,1注册用户,2铜牌用户,3高端用户',
email varchar(255) NOT NULL DEFAULT '' comment 'email',
created_at timestamp null default current_timestamp,
PRIMARY KEY (`id`)
) ENGINE=InnoDB ;
添加测试数据
insert into users(id,user_name)values (1,'管理员');
insert into users(id,user_name)values (2,'用户2');
insert into users(id,user_name)values (3,'用户3');
实现加锁
必须满足的条件,以示例表为例方便理解
1、表引擎必须innodb。
2、必须先开启事务。
3、必须使用 select XXX1 from XXX2 where XXX3 for update;
4、其中的 XXX3 必须有索引,建议使用主键最方便。
尽量不要使用范围条件,可以使用 id=1, 或者 id in (1,3) 这样精确的定位记录的语句。
5、经实际测试,有普通索引的字段也可以。
例如 select * from users where type=1 for update, 给这个 type 加索引的话也行。
加锁后对查改的影响
1、任何会话或连接,当查询到同一行记录时,
如果使用 select XXX1 from XXX2 where XXX3 则没有影响,可以正常查询,无论是否在事务中。
2、任何会话或连接,当查询到同一行记录时,
如果使用select XXX1 from XXX2 where XXX3 for update,则被强行阻塞等待,无论是否在事务
中。
3、任何会话或连接,当修改同一行记录时,
如果使用 update XXX2 set XXX1 where XXX3 ,则被强行阻塞等待,无论是否在事务中。
4、任何会话或连接,当修改包括那行的更多记录时,
如果使用 update XXX2 set XXX1 where XXX4 ,这个 XXX4 包含了 XXX3 的记录和其他记录,则 整个 update 依然被强行阻塞等待,无论是否在事务中。
实现解锁
只要满足以下任意一个条件均可
1、在刚才加锁的 mysql 会话中,commit 事务
2、在刚才加锁的 mysql 会话中,rollback 事务
3、刚才加锁 的 mysql 连接断开。实际是 mysql 服务会自己 rollback 事务
laravel实现排他锁的示例代码:
//开启事务
DB::beginTransaction();
//排他锁
$user = User::lockForUpdate()->find(1);
//这里对用户做一些读写操作。
DB::commit();
//或 DB::rollBack();
mysql排他锁的使用总结及注意事项
1、如果修改例如用户账户余额之类的敏感数据,应该总是在使用update这个语句之前,
最先开事务,再使用 select …. where id = 1 for update,
然后再使用 update 。。。where id =1 , 再提交事务。
2、这种总是先 select … for update的方式,实际是让所有sql修改语句串行执行,而不是并发执行,数据修改时当然肯定不会错,
可是也阻塞了php语句的执行,并发访问高速度也慢。当然悲观锁本身就是这样的。
3、如果想保证数据修改正确,除了这种方法,还有一种方法也可以实现,就是不在数据库查询时加锁,
而是让所有的修改sql的程序语言本身不能并发执行,也可以达到效果。
4、如果想保证数据修改正确,还有一种方法,使用乐观锁的实现。
5、如果想保证数据修改正确,还有一种方法,数据放redis,用redis锁。
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号