GreatSQL社区

搜索

[已解决] 读已提交的隔离级别,在加锁时有类似读未提交的行为

267 3 2024-10-8 14:50
# 版本: mysql 8.0.22


# 表结构:
```sql

CREATE TABLE `tbl_test_lock` (
  `pk_id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `mall_name` varchar(32) NOT NULL COMMENT '名称',
  `status` tinyint NOT NULL DEFAULT '10' COMMENT '状态',
  PRIMARY KEY (`pk_id`),
  KEY `idx_status` (`status`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

```
# 数据:
```sql

mysql> select * from tbl_test_lock;
+-------+-----------+--------+
| pk_id | mall_name | status |
+-------+-----------+--------+
|     3 | a1        |     20 |
|     4 | a2        |     20 |
|     5 | a3        |     20 |
|     6 | a4        |     10 |
|     7 | a5        |     10 |
|     8 | a6        |     10 |
|     9 | a7        |     10 |
|    10 | a8        |     10 |
|    11 | a9        |     10 |
|    12 | a10       |     10 |
|    13 | a11       |     10 |
|    14 | a12       |     10 |
|    15 | a13       |     10 |
+-------+-----------+--------+


```
# 会话1
```sql

begin;
update tbl_test_lock set status=20 where pk_id=6;

```

# 会话2
```sql
begin;
select * from tbl_test_lock where status=20 for update;  -- 阻塞中
```

# 查询锁


# 疑问
1、加锁行为有点奇怪:图中蓝色部分,以线程来看,604850已经获取到idx_status上20, 6的锁,但是后面WAITING状态哪一行数据,又显示它正在获取这个锁。以事务id来看,线程604850给另一个线程605234的事务751803878加了个锁。
2、会话1更改pk_id为6的的数据为20状态,是还没提交的,按隔离级别,会话2不应该被阻塞?符合条件status=20的数据还是最开始那3条,并没有增加。

请大家发表意见,指点下,不胜感激
全部回复(3)
yejr 2024-10-8 16:53:22
可以简单理解成这样:事务751803878要把 pkid=6 的那条记录更新 status=20,需要“提前占位”,所以也要先加锁。
running_db 2024-10-12 13:47:18
yejr 发表于 2024-10-8 16:53
可以简单理解成这样:事务751803878要把 pkid=6 的那条记录更新 status=20,需要“提前占位”,所以也要先 ...

奇怪的是,那个锁是后来那个线程既已获取,又在等待的锁。
yejr 2024-10-12 16:18:56
running_db 发表于 2024-10-12 13:47
奇怪的是,那个锁是后来那个线程既已获取,又在等待的锁。

后面的线程里要对多条记录加锁,部分可获取,部分被阻塞
running_db

9

主题

0

博客

43

贡献

注册会员

Rank: 2

积分
70

助人为乐(铜)勤学好问(铜)

合作电话:010-64087828

社区邮箱:greatsql@greatdb.com

社区公众号
社区小助手
QQ群
GMT+8, 2024-11-23 16:26 , Processed in 0.024306 second(s), 16 queries , Redis On.
快速回复 返回顶部 返回列表