Select for update

select for update 是如何锁定表的?

for update 定义

for update 是一种行级锁,又叫排它锁,一旦用户对某个行施加了行级加锁,则该用户可以查询也可以更新被加锁的数据行,其它用户只能查询但不能更新被加锁的数据行.如果其它用户想更新该表中的数据行,则也必须对该表施加行级锁.即使多个用户对一个表均使用了共享更新,但也不允许两个事务同时对一个表进行更新,真正对表进行更新时,是以独占方式锁表,一直到提交或复原该事务为止。行锁永远是独占方式锁。

只有当出现如下之一的条件,才会释放共享更新锁:

1、执行提交(COMMIT)语句

2、退出数据库(LOG OFF)

3、程序停止运行

概念和用法

通常情况下,select 语句是不会对数据加锁,妨碍影响其他的 DML 和 DDL 操作。同时,在多版本一致读机制的支持下,select 语句也不会被其他类型语句所阻碍。

而 select … for update 语句是我们经常使用手工加锁语句。在数据库中执行 select … for update ,大家会发现会对数据库中的表或某些行数据进行锁表,在 mysql 中,如果查询条件带有主键,会锁行数据,如果没有,会锁表。

由于 InnoDB 预设是 Row-Level Lock,所以只有「明确」的指定主键,MySQL 才会执行 Row lock (只锁住被选取的资料例) ,否则 MySQL 将会执行 Table Lock (将整个资料表单给锁住)。

注意:
1、FOR UPDATE 仅适用于 InnoDB,且必须在事务处理模块(BEGIN/COMMIT)中才能生效。

2、要测试锁定的状况,可以利用 MySQL 的 Command Mode(命令模式) ,开两个视窗来做测试。

验证:

开启事务

查看锁:

1
select *from information_schema.INNODB_TRX;

开启新窗口执行加锁或更新操作:

1
2
3
4
5
6
set session transaction isolation level repeatable read;
set autocommit=0;
begin ;
select *from xxl_job_lock t ; // 可执行
select *from xxl_job_lock t where lock_name='schedule_lock' for update; // 等待锁
update xxl_job_lock set lock_name='schedule_lock3' where lock_name='schedule_lock'; // 等待锁

MySQL 的事务隔离级别?

如何查看 mysql 中的事务隔离级别:

1
2
3
查看系统隔离级别:select @@global.tx_isolation;
查看会话隔离级别(5.0以上版本):select @@tx_isolation;
查看会话隔离级别(8.0以上版本):select @@transaction_isolation;