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

MYSQL事务同时修改单条记录

  • 疑问:Mysql多事务默认情况下,同时修改同一条记录运行修改吗?是否要手动加上for update行锁。

  • 猜想:MySQL 会自动对涉及的数据行加上写锁(排他锁),以确保数据的一致性和隔离性。这是在默认的事务隔离级别 Repeatable Read 下的行为。

  • 验证

第一个事务不结束,并对message_id=40的记录进行修改

BEGIN;
UPDATE message SET message_name = '瓜瓜在哪里' WHERE message_id = 40;
SELECT * FROM message WHERE message_id = 40;

第二个事务同样执行,对该记录进行修改

BEGIN;
UPDATE message SET message_name = '瓜瓜不见了' WHERE message_id = 40;
SELECT * FROM message WHERE message_id = 40;
COMMIT;
  • 结果
    第二个事务,一直处于阻塞状态,知道我42秒将第一个事务COMMIT后,才获得锁进行修改操作。
UPDATE message SET message_name = '瓜瓜不见了' WHERE message_id = 40
> Affected rows: 1
> 时间: 42.577s
  • 结论

在多事务同时修改同一条记录的情况下,MySQL 会自动对涉及的数据行加上写锁(排他锁)。
注意:读该条记录的话不受影响。 不是事务,进行修改同一条也会阻塞。

  • 引出问题:那么自动也可以加锁的话,我怎么验证手动加锁for update是否生效,因为它不手动加锁,也会自动加锁阻止update。
  • 测试1:于是想到不结束的事务,不作修改就不会自动加锁。

第一个事务只做查询

BEGIN;
SELECT * FROM message WHERE message_id = 40;

第二个事务对该记录进行修改,查看是否阻塞

BEGIN;
SELECT * FROM message WHERE message_id = 40;
UPDATE message SET message_name = '瓜瓜不见了' WHERE message_id = 40;
SELECT * FROM message WHERE message_id = 40;
COMMIT;
BEGIN
> OK
> 时间: 0.016sSELECT * FROM message WHERE message_id = 40
> OK
> 时间: 0.02sUPDATE message SET message_name = '瓜瓜不见了' WHERE message_id = 40
> Affected rows: 0
> 时间: 0.016sSELECT * FROM message WHERE message_id = 40
> OK
> 时间: 0.018sCOMMIT
> OK
> 时间: 0.017s
  • 结论:发现不会阻塞正常修改。

  • 测试2:对查询手动加排它锁,FOR UPDATE,其他事务对该记录进行修改,查看是否阻塞。

第一个事务对查询手动加排它锁,FOR UPDATE

BEGIN;
SELECT * FROM message WHERE message_id = 40 for UPDATE;
SELECT * FROM message WHERE message_id = 40;

第二个事务对该记录进行修改

BEGIN;
SELECT * FROM message WHERE message_id = 40;
UPDATE message SET message_name = '瓜瓜不见了' WHERE message_id = 40;
SELECT * FROM message WHERE message_id = 40;
COMMIT;
BEGIN
> OK
> 时间: 0.015sSELECT * FROM message WHERE message_id = 40
> OK
> 时间: 0.016sUPDATE message SET message_name = '瓜瓜不见了' WHERE message_id = 40
> Affected rows: 0
> 时间: 5.325sSELECT * FROM message WHERE message_id = 40
> OK
> 时间: 0.017sCOMMIT
> OK
> 时间: 0.015s
  • 结论:在修改操作是,会有阻塞现象,知道我提交了第一个事务才继续运行。

  • 补充:

    • 自动加锁和where或set的条件字段是否为索引和主键无关。
    • 自动加的锁和手动加的FOR UPDATE锁是同一种类型的锁(排它锁)。
    • 刚开始我以为自动加锁会与隔离级别有关,于是更换了READ-COMMITTED和READ-UNCOMMITTED隔离级别测试,发现事务执行update语句都会自动加锁,影响别的事务。
show variables like '%tx_isolation%';
set tx_isolation='READ-COMMITTED';
set tx_isolation='READ-UNCOMMITTED';
http://www.lryc.cn/news/110978.html

相关文章:

  • 安装skywalking并集成到微服务项目
  • 一支笔,一双手,一道力扣(Leetcode)做一宿
  • Kubernetes(K8s)从入门到精通系列之九:使用kubeadm工具快速安装K8s集群
  • RabbitMQ 教程 | 第11章 RabbitMQ 扩展
  • 一分钟完成centos7安装docker
  • NativePHP:使用PHP构建跨平台桌面应用的新框架
  • 删除这4个文件夹,流畅使用手机无忧
  • 使用Bert预训练模型处理序列推荐任务
  • 将word每页页眉单独设置
  • rust怎么生成随机数?
  • python-Excel数据模型文档转为MySQL数据库建表语句(需要连接数据库)-工作小记
  • 406 · 和大于S的最小子数组
  • xray的 webhook如何把它Hook住?^(* ̄(oo) ̄)^
  • 浅析RabbitMQ死信队列
  • ELK 企业级日志分析系统(ElasticSearch、Logstash 和 Kiabana 详解)
  • 数学建模—多元线性回归分析
  • win10 64位 vs2017 qt5.12.6 pcl1.9.1 vtk8.1.1配置安装步骤
  • 【项目 计网1】4.1 网络结构模式 4.2MAC地址、IP地址、端口
  • uni-app:分页实现多选功能
  • 问道管理:沪指窄幅震荡跌0.18%,有色、汽车等板块走低
  • Kotlin 协程与 Flow
  • 设备管理系统与物联网的融合:实现智能化设备监控和维护
  • 三、从官方源码精简出第1个FreeRTOS
  • __call__函数的用法
  • golang定时任务库cron实践
  • Julia 流程控制
  • 问题解决方案
  • kubernetes基于helm部署gitlab-operator
  • ChatGPT在在线客服和呼叫中心中的应用如何?
  • C++多线程环境下的单例类对象创建