文章目录
介绍
- 介绍
- 加锁情况分析
- 明确指定主键,并且数据真实存在,锁定行
- 明确指定主键,但数据不存在,不加锁
- 主键不明确,锁定整个表
- 无主键,锁定整个表
- 应用场景
1.FOR UPDATE 加的锁是一种行级排他锁,也是一种悲观锁 2.加锁的事务可以查询也可以修改被加锁的数据行,其它事务只能查询但不能修改被加锁的数据行,而且其它事务不能再往这个数据行加任何类型的锁 3.FOR UPDATE 给行加锁,必须在事务控制模块中才能生效 4.FOR UPDATE 仅适用于 InnoDB 5.MyISAM 只支持表级锁,InnoDB 支持表级锁和行级锁
注:不显式执行 START TRANSACTION,执行 DML 语句也是一个事务,默认自动提交。
什么时候释放锁:
1.执行提交或回滚语句 2.退出数据库 3.程序停止运行
加锁情况分析查询 InnoDB 表数据时,只有查询条件中明确指定主键值,MySQL 才会锁定行;否则 MySQL 将会锁定整个表。
假设有下面这张表及数据:
mysql> select * from user;
+----------------------+----------+
| id | NAME |
+----------------------+----------+
| 00000000000000000001 | zhangsan |
| 00000000000000000002 | lisi |
| 00000000000000000003 | libai |
+----------------------+----------+
3 rows in set (0.00 sec)
注:ID 是主键。
明确指定主键,并且数据真实存在,锁定行START TRANSACTION; -- 开始事务
SELECT * FROM user WHERE id=00000000000000000003 FOR UPDATE;
SELECT * FROM user WHERE id=00000000000000000003 and name='lisi' FOR UPDATE;
明确指定主键,但数据不存在,不加锁
SELECT * FROM user WHERE id=0 FOR UPDATE;
主键不明确,锁定整个表
SELECT * FROM user WHERE id3 FOR UPDATE;
SELECT * FROM user WHERE id LIKE '%3%' FOR UPDATE;
注意:不管是否查询到记录,都会锁定表。
无主键,锁定整个表SELECT * FROM user WHERE name='libai' FOR UPDATE;
应用场景
比如火车票订票,在手机屏幕上显示有票,如果没有锁定相关数据,在真正进行出票(扣减锁票)时,你必须重新确定一下这个数据有没有被其他客户端修改过。如果你使用了行级锁,则可以直接出票,所以这个业务场景可以使用 FOR UPDATE 对数据进行加锁。