首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL‘选择更新’行为

MySQL‘选择更新’行为
EN

Stack Overflow用户
提问于 2012-01-13 10:59:02
回答 1查看 29.9K关注 0票数 28

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

案例-1

开启航站楼-1:

//连接到mysql

代码语言:javascript
复制
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

代码语言:javascript
复制
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在航站楼为is.Now -2:

代码语言:javascript
复制
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. 是否意味着无界的select查询(即使是使用阈值参数)。我也尝试过用不同的范围来阻止整个表?
  3. 是否有任何方法可以让事务独立地锁定而不指定记录的字段(也就是说,不使用(或者按照并发锁),写锁是独占的,读取不是。在情况2.1中,虽然记录处于写锁模式,但T2如何读取相同的记录?既然允许这样做,那么锁定它的意义是什么呢?
  4. Case 2.2是可以理解的。

开设了一个终端和一个交易:

代码语言:javascript
复制
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

把它留在那里,打开另一个终端和交易:

代码语言:javascript
复制
mysql> update tracking_number set status=5 where status=0 limit 5; 

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

  1. 为什么会有这种行为?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-19 21:30:43

让我看看你的案子,解释一下这些锁是如何工作的:

1例

T1想要更新测试表中的一些行。这个事务将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希望更新测试表中的一些行(选择更新)。Place位于整个表上,并试图获得行上的S锁,但由于X和S不兼容而失败。

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

希望它能帮上忙

票数 24
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8849518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档