当前位置: 首页 > 面试题库 >

MySQL“选择更新”行为

穆乐逸
2023-03-14
问题内容

根据MySql文档,MySql支持多重粒度锁定(MGL)。

打开终端1:

//连接到mysql

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

mysql> select id, status from tracking_number limit 5 for update;
+----+--------+
| id | status |
+----+--------+
|  1 |      0 |
|  2 |      0 |
|  3 |      0 |
|  4 |      0 |
|  5 |      0 |
+----+--------+
5 rows in set (0.00 sec)
mysql>

离开它打开并打开终端2:

//连接到mysql

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

mysql> select id, status from tracking_number limit 5 for update;

<!-- Hangs here. and after some time it says-->
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

尽管要检索的行很多,但T2等待直到t1完成。

情况2

保持端子1不变,现在位于端子2中:

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

<!-- case 2.1 -->
mysql> select id, status from tracking_number where id=1;
+----+--------+
| id | status |
+----+--------+
|  1 |      0 |
+----+--------+
1 row in set (0.00 sec)

mysql> select id, status from tracking_number where id=2;
+----+--------+
| id | status |
+----+--------+
|  2 |      0 |
+----+--------+
1 row in set (0.00 sec)

<!-- case 2.2 -->
mysql> select * from tracking_number where id=2 for update;
<!-- Hangs here. and after some time -->
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
  1. 但是,为什么在情况1中,T2等待T1锁定的同一行集?

  2. 这是否意味着无限制的选择查询(即使使用limint参数。我也尝试了不同的范围)阻塞了整个表?

  3. 有什么方法可以让事务独立锁定而无需指定记录的字段(即,不使用 where field = value )?

  4. 通常(或按照Java并发锁定),写锁定是排他的,读不是。在情况2.1中,尽管记录处于写锁定模式,但是T2如何读取相同的记录?既然允许这样做,锁定它有什么意义?
  5. 情况2.2被理解。

打开一个终端和一个事务:

mysql> update tracking_number set status=4 where status=0 limit 5;
Query OK, 5 rows affected (0.00 sec)
Rows matched: 5  Changed: 5  Warnings: 0

离开那里,打开另一个终端和交易:

mysql> update tracking_number set status=5 where status=0 limit 5;

直到我提交(或回滚)T1,T2才成功。

  1. 为什么会这样呢?

问题答案:

让我审视您的情况并解释这些锁的工作方式:

1箱

T1想要更新测试表中的某些行。此html" target="_blank">事务将IX锁放在所有表上,将X锁放在前5行上。

T2希望更新测试表中的某些行。此事务将IX(因为IX与IX兼容)锁定在所有表上,并尝试到前5行,但由于X与X不兼容而无法执行

所以我们很好。

2.1案例

T1想要更新测试表中的某些行。此事务将IX锁放在所有表上,将X锁放在前5行上。

T2希望从测试表中选择一些行。而且它不会放置任何锁(因为InnoDB提供了非锁定读取)

2.1案例

T1想要更新测试表中的某些行。此事务将IX锁放在所有表上,将X锁放在前5行上。

T2想要更新(选择更新)测试表中的某些行。将IS放在整个表上,并尝试在行上获取S锁,但由于X和S不兼容而失败。

还请始终注意隔离级别:不同的级别会导致不同的机制释放/获取锁

希望能帮助到你



 类似资料:
  • 问题内容: 有没有简单的方法来选择更新的行? 我试图每次读取行时都存储时间戳,以便能够删除长时间未读取的数据。 首先,我首先尝试执行查询,甚至发现有点慢但是简单的解决方案,例如 但我仍然想找到一种正常的方法来做到这一点。 我还认为先更新时间然后选择更新的行应该容易得多,但是即使如此,我也没有找到任何东西 问题答案: 声明该列,如下所示: 然后,每当更新一行时,该列就会自动更新。 更新: 我认为没有

  • 如果我分别创建这两个MySQL触发器,两个触发器都执行OK。但我无法将它们组合起来,使其能够乘以持续时间x速率。 如果存在,则删除触发器;为每一行更新后创建definer=@TRIGGERSET@rate=(从语言中选择速率,其中languages.idlanguages=contracts.languages_idlanguagejes); 如果存在,则删除触发器;CREATE definer=

  • 问题内容: 我需要帮助或想法如何编写它,一个mysql语句。当特定列的值更改时,我需要选择一行。此后具有相同值的行不应选择。例如,我们有一个像这样的表,用以下值填充: 如果我想在status_1更改时选择行,则查询应选择ID为1和5的行,如果我正在使用status_2的ID为:1、3、5、7的行,并且如果我使用status_3的所有ID,则为ID 。希望有人可以在过去的所有时间里为我提供帮助。 提

  • 本文向大家介绍MySQL LIMIT选择单行,包括了MySQL LIMIT选择单行的使用技巧和注意事项,需要的朋友参考一下 要在MySQL中选择一行,可以使用LIMIT。首先,让我们创建一个表。创建表的查询如下- 使用insert命令在表中插入一些记录。查询如下- 使用select语句显示表中的所有记录。查询如下- 以下是输出- 这是使用LIMIT从表中选择一行的查询- 以下是输出-

  • 问题内容: 我有一个mysql问题。 我的网站上有一个新闻版块,我想显示两个最新项目。如果我做: 它选择了最新的项目,现在我要选择倒数第二个项目。 你们知道怎么做吗? /// 编辑 现在它不起作用了,这是我的代码:(我已经包含了;)) 问题答案: -选择最后2个项目 -仅选择第二项

  • 我有一个名为“survey_product”的表,其结构如下: 此表存储通过系统订购的产品。 下面是该表中的一些数据记录: 以上我们有3个订单(订单号2、3和4)。 我需要获取product\u id=21但product\u id=20的所有订单的order\u id(订单中的其他product\u id不相关-我只对21和20感兴趣)。 然后我需要知道product\u id为20和21的订单