提问人:theBackendLearner 提问时间:11/16/2023 最后编辑:theBackendLearner 更新时间:11/16/2023 访问量:142
如何知道交易是否连续持有独占锁?
how to KNOW if a transaction holds exclusive lock in a row?
问:
我正在学习交易、锁等,我想知道如何知道交易是否连续持有独占锁
我尝试使用 MySQL 命令行模拟它,但我不确定这是否是了解事务是否在一行中持有独占锁的正确方法,您能确认我的测试是否正确吗?我知道它正在起作用,因为我看到了它,但也许这只是一个巧合。
我尝试按以下顺序进行此测试:
在连接 1 中打开事务:
begin;
UPDATE users SET rol = 'Admin' WHERE email LIKE '%example.net%';
Query OK, 182 rows affected (0.03 sec)
Rows matched: 182 Changed: 182 Warnings: 0
现在,在连接 2 中打开另一个事务(这是满足连接 1 条件的行):
begin;
UPDATE users SET rol = 'Admin' WHERE id = 11; // Blocked, it's waiting
现在,我将关闭连接 1 中的事务:
rollback;
Query OK, 0 rows affected (0.02 sec)
立即(自动)连接 2:
Query OK, 1 row affected (18.33 sec) // "Free"
Rows matched: 1 Changed: 1 Warnings: 0
rollback; // I close the another transaction
- 如果我上面的例子知道事务是否在某些行上持有独占锁是正确的,那么它是否适用于并且因为它也设置了独占锁?
DELETE
SELECT ... FOR UPDATE
另一方面,文档内容如下:
默认情况下,MySQL在启用自动提交模式的情况下运行。这意味着,当不在事务中时,每个语句都是原子的,就好像它被 START TRANSACTION 和 COMMIT 包围一样。不能使用 ROLLBACK 撤消效果;但是,如果在语句执行过程中发生错误,则会回滚该语句。
- “每个语句都是原子的”是指单个语句(只有一个)吗?
- 即使条件“跨越”多行(例如连接 1)单个语句仍然是原子的吗?
UPDATE
答:
2赞
Bill Karwin
11/16/2023
#1
- 如果我上面的例子知道事务是否在某些行上持有独占锁是正确的,那么它是否适用于 DELETE 和 SELECT ...FOR UPDATE,因为它还设置了排他锁?
是的,您可以对其他锁定语句运行类似的测试来证明这一点。
- “每个语句都是原子的”是指单个语句(只有一个)吗?
是的,自动提交模式意味着每个语句启动并提交一个事务。
- 即使条件“跨越”多行(例如连接 1 的 UPDATE),单个语句仍然是原子的吗?
是的。在默认事务隔离级别中,该语句在它检查的所有行上获取锁。这可能比受 UPDATE 影响或由 SELECT 返回的行多,因为查询中的条件可能会筛选行。
例如,在您的示例 UPDATE 中:
UPDATE users SET rol = 'Admin' WHERE email LIKE '%example.net%';
具有通配符模式的条件将检查表中的所有行,即使您已在要搜索的列上定义了索引也是如此。因此,此更新将锁定所有行,即使是那些不满足条件的行。LIKE
该语句以原子方式获取锁。这意味着它要么获取所需的所有锁,要么如果失败(例如,因为某些行已被另一个会话锁定),它必须释放它试图在该语句中获取的其他锁,即使是那些本来会成功的锁。
评论
0赞
theBackendLearner
11/16/2023
文档说:“在InnoDB中,所有用户活动都发生在事务中。如果启用了自动提交模式,则每个 SQL 语句都会自行形成一个事务。- 这是否意味着任何单个语句(只有一个),例如 (没有被“明确”的交易包围)会像 ?@Bill 卡文UPDATE table SET column = 'something' WHERE id > 1;
begin; UPDATE table SET column = 'something' WHERE id > 1; commit;
0赞
Bill Karwin
11/16/2023
是的。我想我已经回答了这个问题。
0赞
theBackendLearner
11/16/2023
对不起,只是我是新来的,有时我觉得他们指的是不同的东西。它看起来是幕后包围的,因为“隐式”是以防单个语句失败,对吧?@Bill 卡文commit;
rollback;
0赞
Bill Karwin
11/16/2023
如果失败,则该语句无效。这意味着该声明是原子的。它不更新任何行,并且它获取的任何锁都会被释放。在这一点上,它是提交还是回滚事务并不重要,因为无论哪种方式都没有效果。
1赞
theBackendLearner
11/17/2023
伟大!!!感谢您引用文档,最好使用官方引用来支持信息。我仍然没有阅读所有文档,这就是为什么我没有意识到这一点。对不起,由于我的声誉,我不能给你的答案+1,但是当我有一些声誉时,我会停下来留下我的+1。
评论
show engine innodb status
SHOW CREATE TABLE users