mysql update多字段时引发的一个问题

 【1】问题描述

该问题已在mysql5.7  8.0 均已测试出现

create table test111(id int primary key auto_increment,a int ,b int);

update操作前          

  

 update操作后

  

同理(无论加不加主键索引,效果均如上图!)

我们发现,update多个列时,如果前一个列的值被改变,后一个列表达式中如果有引用到被改变列的值,那么是修改后的;

本来应该是 最终 a=15,b=30的,结果b=35了! 这并不是我们想要的结果;

【2】分析解决

(2.1)其他数据库会这样吗?不会

以mssql为例子

  

这里  a=a+2,b=b+a  ,这里的 b=b+a 是  a=a+2 操作之前的数据

oracle

  

与上面一样,这里就不解释了

(2.2)为什么mysql会这样?

无论我测试8.0/5.7 版本,都会这样;

核心是因为 mysql 有 mvcc ??(参考文档中的文章是这样说的)

  但我感觉,其实是因为

1.我感觉多列update

2.其实是拆成了 一个一个 update

(2.3)总结

1=》其他数据库:查出一版结果信息来后,锁定目标行数据加载到内存,然后引用次结果集上数据做计算

  =》一次性计算出所有结果=》生成的新结果集记录到脏页;

  =》注意这里的计算是整个多列update所有表达式都一起计算的;

2=》mysql数据库:查出一版结果信息来后,锁定目标行数据加载到内存,然后引用次结果集上数据做计算曹邹

  =》会从左到右的执行 update 的 多列更新,先最左边这个,也就是说性质是类似拆成了多个update的形式;

  如:

    update test11 set a = a+5,b = b+a where id=1;

    先执行 update test11 set a=a+5;

    =》然后再 update test11 set b=b+a;  会重新来一遍当前读,所以这里的 a 是上一个 a=a+5 之后的结果值了;

【3】解决方案

(方法1)如果有依赖其他列操作的update,那么则一列一列update

(方法2)反向计算回去:  

  常规:update test11 set a = a+5,b = b+a where id=1;

  反向计算回去:update test11 set a = a+5,b = b+a-5 where id=1;

【参考文档】

https://www.cnblogs.com/keme/p/13101115.html

原文地址:https://www.cnblogs.com/gered/p/15378423.html