当前位置: 首页 > news >正文

SELECT ... FOR UPDATE 加锁后,其他线程能读取数据吗

在执行 SELECT * FROM table WHERE ... FOR UPDATE 语句时,MySQL 会对查询结果集中的行加 排他锁(X锁)。这种锁的行为会影响其他事务对这些行的读写操作。以下是具体的影响:


1. 加锁后的效果

  • 当前事务

    • 对查询结果集中的行加排他锁(X锁)。

    • 可以继续读取和修改这些行。

  • 其他事务

    • 不能对这些行加锁或修改(即不能执行 UPDATEDELETE 或 SELECT ... FOR UPDATE)。

    • 可以读取这些行(如果隔离级别允许),但读取的数据可能是旧版本(取决于隔离级别)。


2. 不同隔离级别下的行为

2.1 读未提交(READ UNCOMMITTED)
  • 其他事务可以读取被锁定的行,即使这些行尚未提交(脏读)。

  • 其他事务不能修改被锁定的行。

2.2 读已提交(READ COMMITTED)
  • 其他事务可以读取被锁定的行,但只能读取已提交的数据(不会脏读)。

  • 其他事务不能修改被锁定的行。

2.3 可重复读(REPEATABLE READ)
  • 其他事务可以读取被锁定的行,但只能读取事务开始时的数据快照(不会脏读或不可重复读)。

  • 其他事务不能修改被锁定的行。

2.4 串行化(SERIALIZABLE)
  • 其他事务不能读取或修改被锁定的行,直到当前事务提交或回滚。


3. 示例

假设有两个事务:事务 A 和事务 B。

事务 A

sql

复制

START TRANSACTION;
SELECT * FROM t WHERE id = 1 FOR UPDATE;  -- 对 id = 1 的行加排他锁
-- 事务 A 可以继续读取或修改 id = 1 的行
事务 B
  • 尝试读取

    SELECT * FROM t WHERE id = 1;  -- 可以读取(取决于隔离级别)
    • 在 读未提交 隔离级别下,事务 B 可以读取事务 A 未提交的数据。

    • 在 读已提交 或更高隔离级别下,事务 B 只能读取已提交的数据。

  • 尝试修改

    UPDATE t SET name = 'Bob' WHERE id = 1;  -- 会被阻塞,直到事务 A 提交或回滚
    • 事务 B 不能修改被锁定的行。

  • 尝试加锁

    SELECT * FROM t WHERE id = 1 FOR UPDATE;  -- 会被阻塞,直到事务 A 提交或回滚
    • 事务 B 不能对锁定的行加锁。


4. 总结

  • 执行 SELECT ... FOR UPDATE 后,其他事务:

    • 可以读取被锁定的行(具体行为取决于隔离级别)。

    • 不能修改或加锁被锁定的行,直到当前事务提交或回滚。


http://www.mrgr.cn/news/93416.html

相关文章:

  • 自然邻居搜索算法(NaN-Searching)
  • RabbitMQ知识点
  • 8. 机器人模型训练与评估(具身智能机器人套件)
  • K8s 1.27.1 实战系列(三)安装网络插件
  • AI 编译器学习笔记之十六 -- TVM
  • 基于PyMuPDF与百度翻译的PDF翻译处理系统开发:中文乱码解决方案与自动化排版实践
  • qt作业day5
  • 计算机网络笔记(一)——1.1计算机网络在信息时代中的作用
  • Android项目优化同步速度
  • 【办公类-99-03】养老护理初级考题抽取(2套大题抽1+7小套题抽2——共有42种可能)
  • TDengine SQL查询语法
  • MuBlE:为机器人操作任务规划提供了逼真的视觉观察和精确的物理建模
  • 2021年高教社杯全国大学生数学建模A题——基于几何模型的“FAST”主动反射面的形状调节
  • HuggingFace 模型转换为 GGUF/GGML
  • 【人工智能学习之局部极小值与鞍点】
  • 深度学习 PyTorch 中 18 种数据增强策略与实现
  • 全新方案80M/S,告别限速!
  • 自定义录制,解锁全部功能!
  • Java面经
  • K8s 1.27.1 实战系列(一)介绍及准备工作