mysql 更新时,旧值与新值相同会怎么做?

文章目录

  • 1 问题描述
  • 2 验证
    • 2.1 验证猜想1
    • 2.2 验证猜想2
  • 3 结论
  • 4 mysql 为什么这么设计呢?

1 问题描述

创建一张表t,插入一行数据

mysql> CREATE TABLE `t` (
`id` int(11) NOT NULL primary key auto_increment,
`a` int(11) DEFAULT NULL
) ENGINE=InnoDB;
insert into t values(1,2);

现在表t中已经有id = 1,a=2这一行
在这里插入图片描述
执行更新语句,更新id=1这一样,将a的值修改为2(逻辑上值不变)

 update t set a = 2 where id = 1;

在这里插入图片描述
可以看到返回结果,0 rows affected。
仅从现象上看,mysql在处理这个条sql语句时,可能是以下三种情况:

  1. 命令执行到server层返回,因为执行更新之前需要先读出数据,server层的执行器拿到id=1的这一行,发现a=2,于是不会调用InnoDB修改行字段的接口,直接返回。没加写锁
  2. 命令执行到Innodb层返回,server层调用了InnoDB修改行字段的接口,InnoDB对数据加上了写锁,然后进行当前读,读出最新的a的值是2,发现与旧值相同,于是不更新,直接返回。加了写锁,没执行更新
  3. InnoDB认真执行了修改操作,InnoDB对数据加上了写锁,然后进行当前读,读出最新的a的值是2,发现与旧值相同,但是还是执行了一次更新操作,将2赋值给a,然后记录到redo log中,经过两阶段提交,结束事务。也就是一个完整的,正常的更新过程

2 验证

2.1 验证猜想1

猜想1很好验证,如果没加写锁,让事务A和事务B并发的执行更新语句,如果后执行的事务没有被阻塞,则证明猜想1正确。

时间事务A事务B
t0begin;
t1begin;
t2update t set a = 2 where id = 1;
t3update t set a = 2 where id = 1;
t4commit;
t5commit;

事务A
在这里插入图片描述

事务B
在这里插入图片描述
事务B的update语句被阻塞,等到事务A commit后才会提交。说明update过程中是加锁了的,猜想1不正确。

2.2 验证猜想2

猜想2是加锁,但是没有执行更新逻辑。可以采用InnoDB,MVCC机制来验证,MVCC就是在事务整个过程中会拿到一致性视图,对普通读进行复用,达到可重复读的隔离级别。

时间事务A事务B
t0begin;
t1select * from t where id = 1 // (1,2)
t2begin;
t3update t set a = 3 where id = 1;
t4commit;
t5select * from t where id = 1 // (1,2)
t6commit;

由于MVCC的机制,且InnooDB引擎默认设置的隔离级别是可重复度,所以事务A在开始的时候就会创建一致性视图,整个事务过程中进行复用。
所以,第一句select和第二句select查到的都是(1,2),因为事务B的更新对事务A是不可见的。
接下来,我们对事务A再加一条更新的sql语句:

时间事务A事务B
t0begin;
t1select * from t where id = 1 // (1,2)
t2begin;
t3update t set a = 3 where id = 1;
t4commit;
t5update t set a = 3 where id = 1;
t6select * from t where id = 1 // (1,3)
commit;

t5时刻,事务A执行了更新,更新语句是当前读,不是快照读,所以更新语句会读取到当前表中最新的数据,事务A读出来此时a=3,而自己要更新的也是3,旧值与要更新的新值相同,根据猜想2,事务A此次更新不会执行。也就是,InnoDB 的undo log中保留的行数据还是事务B更新的版本,而这个版本的更新是对事务A是不可见的,也就是后续的select语句读出来的结果应该还是(1,2)。但此时,事务A读出来的结果却是(1,3)。说明猜想2错误,InnoDB确实做了更新,并记录了undo log 和 redo log。

3 结论

mysql要更新一条行记录是,即使这条行记录的旧值与要更新的新值相同,mysql也会按部就班地进行更新。

4 mysql 为什么这么设计呢?

我想有以下几点原因:

  1. 数据一致性,InnoDB会按照用户要求的进行操作,即使这个操作显而易见地可以优化,比如要更新的值与旧值相同。这是为了保证数据一致性,如果让InnoDB决定哪些操作需要跳过,可能会导致数据不一致。
  2. 事务,因为update这条语句可能只是这个事务的其中一环,如果这个语句不按照正常的更新流程走,再发生事务回滚时,就回滚不了。
  3. 触发器,如果有表触发器,比如只要update执行了就触发的触发器,如果innodb自行跳过,这些触发器就不会执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/752796.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第111讲:Mycat实践指南:固定Hash算法分片下的水平分表详解

文章目录 1.固定Hash算法分片的概念1.1.固定Hash算法的概念1.2.固定Hash算法是如何将数据路由到分片节点的 2.使用固定Hash算法分片对某张表进行水平拆分2.1.在所有的分片节点中创建表结构2.2.配置Mycat实现固定Hash算法分片的水平分表2.2.1.配置Schema配置文件2.2.2.配置Rule分…

unityprotobuf自动生成C#

Release Protocol Buffers v3.19.4 protocolbuffers/protobuf GitHub 导入Source code 里面的 csharp/src/Google.Protobuf 进入Unity 拷贝其他版本的 System.Runtime.CompilerServices.Unsafe进入工程 使用protoc-3.19.4-win32 里面的exe去编译proto文件为C# using Sys…

MybatisPlus-Generator自定义模版生成CRUD、DTO、VO、Convert等

个人博客:无奈何杨(wnhyang) 个人语雀:wnhyang 共享语雀:在线知识共享 Github:wnhyang - Overview 简介 如标题所言,本篇文章介绍如何使用MybatisPlus-Generator自定义模版生成CRUD、DTO、V…

Redis实战——查询缓存缓存穿透、雪崩、击穿

目录 为什么要使用缓存缓存的作用缓存的成本如何使用缓存缓存模型和思路缓存更新策略数据库和缓存不一致解决方案数据库和缓存不一致采用什么方案对比删除缓存与更新缓存如何保证缓存与数据库的操作同时成功/同时失败先操作缓存还是先操作数据库? 实现商铺缓存与数据…

Tensorflow笔记(二):激活函数、优化器等、神经网络模型实现(商品销量预测)

import tensorflow as tf import numpy as np from tqdm import tqdm# ----------------------------- tensor常用函数2 ----------------------------------- a tf.constant([1, 2, 3, 1, 2]) b tf.constant([0, 1, 3, 4, 5]) c tf.where(tf.greater(a, b), a, b) # 若a&g…

Linux下的多线程编程:原理、工具及应用(4)

🎬慕斯主页:修仙—别有洞天 ♈️今日夜电波:Flower of Life—陽花 0:34━━━━━━️💟──────── 4:46 🔄 ◀️ ⏸ ▶️ ☰ …

RuoYi-Vue开源项目2-前端登录验证码生成过程分析

前端登录验证码实现过程 生成过程分析 生成过程分析 验证码的生成过程简单概括为:前端登录页面加载时,向后端发送一个请求,返回验证码图片给前端页面展示 前端页面加载触发代码: import { getCodeImg } from "/api/login&q…

Spring6--基础概念

1. 概述 1.1. Spring是什么 Spring 是一套广泛应用于 Java 企业级应用开发领域的轻量级开源框架,由 Rod Johnson 创立,旨在显著降低 Java 企业应用的复杂性,缩短开发周期,并提升开发效率。Spring 不仅适用于服务器端开发&#x…

三个案例,带你看懂智能时代支撑降本增效的底层逻辑

2003年,“神舟五号”成功登上太空,2007年,乔布斯初代苹果发布会,2016年“天宫二号”与“神州十一号”自动交会对接成功,2022年ChatGPT横空出市。 科技发展速度令人惊叹,一不留神就步入了下一个科技时代&am…

【vue elementUI】el-select和弹出框el-option样式调整,::v-deep失效

组件自带样式: 修改后样式: 注意修改弹出框样式需要修改一个属性: 此属性默认值为true,此时可以看到弹出框是放在外面的,没有在el-select里面。此时设置弹窗样式会不生效,::v-deep无效。 需要将此属性改为f…

JavaScript练手小技巧:数字反转时钟

样式基于博主的这篇文章: CSS3技巧38:3D 翻转数字效果-CSDN博客 既然可以实现翻转数字了,肯定就可以跟 JS 相结合去完成一些数字展示效果。 比如,数字反转时钟。 为了方便,所有 HTML 数字根据时间动态生成。因此&a…

vue3 element plus 上传下载

文章目录 上传下载 上传 /* html */ <el-upload v-model"fileId" class"avatar-uploader" ref"exampleUploadRef" :file-list"fileList" :show-file-list"false" action"/ys-three-year/ThreeReport/uploadFile&q…

Coarse-to-Fine Latent Diffusion for Pose-Guided Person Image Synthesis阅读笔记

连更&#xff01;&#xff01; 0 Abstract 先前的姿势引导图像合成方法简单的将人的外观与目标姿势进行对齐&#xff0c;这容易导致过拟合&#xff0c;因为缺乏对source person image的high-level semantic understanding&#xff1b;文章开发了一种新的训练范式&#xff1a;…

mudo服务器测试一

目录 长连接测试 测试代码 客户端 服务端 超时连接测试 测试代码 客户端 服务端 错误请求测试 测试代码 场景一 客户端 服务端 场景二 客户端 服务端 长连接测试 测试代码 /*长连接测试1: 创建一个客户端持续给服务器发送数据,直到超过时间看是否正常*/ #inc…

实用工具推荐----geek 卸载软件的神器

Geek Uninstaller 是一款软件卸载工具。它提供简单易用的界面和强大的卸载功能&#xff0c;能快速扫描和识别应用程序&#xff0c;并彻底删除与之相关的文件和注册表项&#xff0c;确保完全清除应用程序。它还可以监视应用程序安装过程&#xff0c;并记录创建的文件和注册表项…

计算机组成原理练习-计算机性能指标

CPU时间与IO时间 ------------------------------------------------------------------------------------------------------------------------------- 1.假定基准程序A在某计算机上的运行时间为100秒&#xff0c;其中90秒为CPU时间&#xff0c;其余 为l/O时间。若CPU速度…

WebGIS之实现查询地区天气并让地区高亮

一.预览>> 二.思路>> 根据搜索框的内容来进行页面视角的切换&#xff0c;对应的地区高亮&#xff0c;右边有关天气的地方实时更新&#xff0c;并且因为代码体量非常小&#xff0c;并没有选择在框架下完成。直接一个html文件搞定了&#xff0c;但实际上还是有一些坑…

带有超令牌采样的视觉转换器

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 摘要Abstract文献阅读&#xff1a;带有超令牌采样的视觉转换器1、研究背景2、方法提出3、优势4、实验5、贡献 二、StokenAttention代码学习 摘要 本周主要阅读了CV…

Elasticsearch数据存储优化方案

优化Elasticsearch数据存储有助于提升系统性能、降低成本、提高数据查询效率以及增强系统的稳定性和可靠性。通常我们再优化Elasticsearch数据存储会遇到一些问题&#xff0c;导致项目卡壳。以下是优化Elasticsearch数据存储的一些重要作用&#xff1a; 1、问题背景 在某些场景…

AI系统性学习03—ChatGPT开发教程

文章目录 1、OpenAI关键概念⭐️2、OpenAI SDK介绍3、OpenAI API KEY&API 认证3.1 REST API安全认证 4、OpenAI模型⭐️4.1 模型分类4.2 GPT44.3 GPT-3.54.4 Embeddings 5、OpenAI快速入门6、Function calling(函数调用)⭐️⭐️⭐️6.1 应用场景6.2 支持function calling的…