MySQL 的共享锁和排它锁以及自动提交

分两种锁
共享锁: SELECT … LOCK IN SHARE MODE
排它锁: SELECT … FOR UPDATE

1.手动提交 排它锁

关闭 MySQL 自动提交
Set autocommit = 0;

窗口1执行命令

mysql> select * from stu where id=1 for update;
+----+------+-----+---------+
| id | name | num | version |
+----+------+-----+---------+
|  1 | 张三 |  86 |       0 |
+----+------+-----+---------+
1 row in set (0.04 sec)

窗口2执行命令,因为窗口1未执行 commit 操作,以至于窗口2阻塞无法读取

mysql> select * from stu where id =1 for update;
1205 - Lock wait timeout exceeded; try restarting transaction

窗口2执行select语句中不带 for update,那么则不影响。

mysql> select * from stu where id =1 ;
+----+------+-----+---------+
| id | name | num | version |
+----+------+-----+---------+
|  1 | 张三 |  86 |       0 |
+----+------+-----+---------+
1 row in set (0.05 sec)

测试完成 开启自动提交

Set autocommit = 1;

2.手动提交 数据更新操作

关闭自动提交

Set autocommit = 0;

进行数据更新

mysql> update stu set name=111 where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

此时,还未进行 commit 操作,数据表中的数据未有变化

MySQL 的共享锁和排它锁以及自动提交

执行 commit 之后

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

MySQL 的共享锁和排它锁以及自动提交

测试完成,开启自动提交

Set autocommit = 1;

总结

在未关闭自动提交前提下(即自动提交已开启情况下),且不是在事务中,那么以下SQL语句的锁功能并不能生效。

共享锁: SELECT … LOCK IN SHARE MODE
排它锁: SELECT … FOR UPDATE

若是,关闭了自动提交,之后的更新操作都需要 进行 commit 提交。不然数据不会被修改。

若是,关闭了自动提交,之前加锁的数据都需要 进行 commit 提交进行解锁。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 1

开启自动提交的情况下,且不是在事务中,那么以下 SQL 语句的锁功能并不能生效。这应该不对吧?不是锁功能不能生效,是因为自动提交,当你SQL语句一执行,就commit了。 开启自动提交的情况下,一条SQL语句就默认是一个事务。

2年前 评论
木大大 (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!