专栏首页开发技术记一次线上问题 → 对 MySQL 的 ON UPDATE CURRENT_TIMESTAMP 的片面认知

记一次线上问题 → 对 MySQL 的 ON UPDATE CURRENT_TIMESTAMP 的片面认知

开心一刻

  老婆痛经,躺在沙发上,两岁的女儿看着她问道

  女儿:妈妈,你怎么了

  老婆:妈妈肚子痛

  女儿:哦,妈妈你头疼

  老婆:不是头疼,妈妈是肚子疼

  女儿用她的不锈钢饭碗砸向老婆的额头,说道:妈妈,你哪里疼

  老婆:头疼,头疼

  老婆幽怨的看着我,说道:这姑娘随你还是随我

  我低着头,小声地说道:我都被你欺负成啥样了,你说姑娘随谁?

问题背景

  需求背景

  需求:对商品的上架与下架进行管控,下架的商品不能进行销售

    上架与下架的管控,在我负责的项目(单据系统)中实现;销售的控制则是在另外一个项目(POS系统)中实现

    POS系统定时的从单据系统中拉取数据,并对商品的销售进行控制

  MySQL 版本: 5.7.20-log

  单据系统设计了两张表:

DROP TABLE IF EXISTS t_ware_on_off_bill;
CREATE TABLE `t_ware_on_off_bill` (
  `id` BIGINT(19) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `bill_code` VARCHAR(45) NOT NULL COMMENT '单据编号',
  `bill_type` TINYINT(2) NOT NULL DEFAULT 1 COMMENT '单据类型(1=下架,2=上架)',
  `bill_status` TINYINT(2) NOT NULL COMMENT '单据状态(1=草稿,2=已提交,3=审核中,4=已生效,5=已取消)',
  `is_delete` TINYINT(2) NOT NULL DEFAULT '2' COMMENT '是否删除标识(1-是,2-否)',
    `note` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '备注',
  `create_user` BIGINT(19) NOT NULL COMMENT '创建人id',
  `create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
  `modify_user` BIGINT(19) NOT NULL COMMENT '最终修改人',
  `modify_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '最终修改时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB COMMENT='商品上架下架单';

DROP TABLE IF EXISTS t_ware_on_off_bill_detail;
CREATE TABLE `t_ware_on_off_bill_detail` (
  `id` BIGINT(19) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `bill_id` BIGINT(19) NOT NULL COMMENT '商品上架下架单的id',
  `ware_code` BIGINT(19) NOT NULL COMMENT '商品编号',
  `note` VARCHAR(255) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB COMMENT='商品上架下架单明细';

  实际上,表的字段不止这么多,但因为表的字段的多少不影响问题的出现,所以也就简化了表结构

  下游系统根据 modify_time 定时进行数据的增量同步( t_ware_on_off_bill 和 t_ware_on_off_bill_detail 都会进行更新)

  部分数据未同步

  结果出现了部分数据未同步的情况

  先来复现下问题,初始数据如下

  此时的 modify_time 的值是 2021-09-08 21:18:52.602

  我们来执行下更新操作

  可以看到对 t_ware_on_off_bill 的更新结果是: 受影响的行: 0 , modify_time 并未进行更新,其值仍是 2021-09-08 21:18:52.602

  但是 t_ware_on_off_bill_detail 是实实在在存在更新的

  这就导致POS系统通过 modify_time 没有增量同步最新的商品明细

  问题来了:明明对 t_ware_on_off_bill 的 N 个字段进行了 SET 操作,为什么没有记录受影响(modify_time 为什么不更新)

探究真相

  我相信此时很多小伙伴都认为楼主是这个

  菜不可怕,怕的是我们不敢面对它;有问题,我们就去找原因,然后解决它(菜的好理直气壮...)

  追查原因

  其实 MySQL 官方文档中有说明:11.2.6 Automatic Initialization and Updating for TIMESTAMP and DATETIME

  两种情况会进行自动更新成系统当前时间

    1、insert 行时,该列没有值

    2、该行的任意列的值改变了

  此时,相信大家都知道原因了吧

  虽然这个 SQL 很长,SET 了好几个字段,但是不满足上述两点中的任意一点,那么 modify_time 也就不会更新成系统当前时间了

  解决问题

  原因是找到了,如何解决问题了?

  官方文档里面也说明了,显示的设值,也就是我们显示的指定 modify_time 的值,像这样

  我们来看看实际结果

  当然,解决方案不止这一种,各位可以在评论区畅所欲言

总结

  1、MySQL 自动设置成系统当前时间是有条件的,否则是不会更新的哦

    insert 行时,该列没有值

    该行的任意列的值改变了

  2、给大家留个疑问:为什么要有任意列的值改变了,MySQL 才会自动更新 modify_time 成当前系统时间,而不是只要有 SET 就更新 modify_time 成当前系统时间

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • MySQL timestamp类型列值自动更新

    MySQL中使用timestamp定义字段,默认情况下会给字段添加自动更新的属性,本文将分析这个自动更新的设置。 问题概述 一个表中定义了两个timestam...

    JavaQ
  • explicit_defaults_for_timestamp参数导致复制中断

    explicit_defaults_for_timestamp是从5.6.6引入的一个新参数,默认是off。 作用:对TIMESTAMP类型列的默认值和NULL...

    MySQL轻松学
  • Entity Framework Core 实现MySQL 的TimeStamp/RowVersion 并发控制

    将通用的序列号生成器库 从SQL Server迁移到Mysql 遇到的一个问题,就是TimeStamp/RowVersion并发控制类型在非Microsoft ...

    张善友
  • 关于mysql字段时间类型timestamp默认值为当前时间问题--Java学习网

    今天把应用部署到AWS上发现后台修改内容提交后程序报错,经过排查发现是更新数据的时候,有张数据表中的一个timestamp类型的字段默认值变成了"0000-00...

    用户1289394
  • 时间戳,这样用就对了

    时间戳字段在MySQL中经常使用到,比如需要记录一行数据创建的时间或修改的时间时,我们通常会使用时间戳即timestamp字段。本篇文章主要介绍timestam...

    MySQL技术
  • 将MySQL去重操作优化到极致

    源表t_source结构如下: item_id int, created_time datetime, modified_time datetime, ...

    用户1148526
  • 将MySQL去重操作优化到极致之三弹连发(二):多线程并行执行

            上一篇已经将单条查重语句调整到最优,但该语句是以单线程方式执行。能否利用多处理器,让去重操作多线程并行执行,从而进一步提高速度呢?比如我的实验环...

    用户1148526
  • MySQL数据字典提示1146不存在的问题解决

    最近某套MySQL因为磁盘挂载问题,异常宕机,拉起后,数据库能正常访问了,但是在error.log一直提示这个错误,

    bisal
  • explicit_defaults_for_timestamp参数详解

    explicit_defaults_for_timestamp 系统变量决定MySQL服务端对timestamp列中的默认值和NULL值的不同处理方法。此变量自...

    MySQL技术
  • MySQL add/drop字段时报主键冲突

    错误提示是主键冲突,但是当我们去查询 id= 7458421 时,并无此记录。是不是很奇怪?遇到这种情况,一般有如下场景:

    用户1278550
  • 小弟问我:为什么MySQL不建议使用delete删除数据?

    我负责的有几个系统随着业务量的增长,存储在MySQL中的数据日益剧增,我当时就想现在的业务方不讲武德,搞偷袭,趁我没反应过来把很多表,很快,很快啊都打到了亿级别...

    敖丙
  • Kafka Connect JDBC Source MySQL 增量同步

    上一篇文章 Kafka Connect JDBC Source MySQL 全量同步 中,我们只是将整个表数据导入 Kafka。这对于获取数据快照很有用,但并不...

    smartsi
  • MySQL日期和时间类型笔记

    最近在看《MySQL技术内幕:SQL编程》并做了笔记,这是一篇笔记类型博客,分享出来方便自己复习,也可以帮助其他人

    SmileNicky
  • 深入mysql外键关联问题的详解--Java学习网

    今儿继续再看老师给推荐的深入浅出mysql数据库开发这本书,看到innodb数据库的外键关联问题时,遇到了一个问题,书上写的是可以对父表进行修改,从而同步到子表...

    用户1289394
  • 关于MySQL的时间类型,我简单说两句

    MySQL支持的时间类型有:DATE、TIME、DATETIME、TIMESTAMP、YEAR。它们的区别,主要在于取值范围的不同。此外,TIMESTAMP、D...

    腾讯IVWEB团队
  • 实用 SQL 语句收藏这篇就够了

    语法:create index index_name on table_name (column_name)

    我是一条小青蛇
  • 数据库安全·时间一致性

    以下节选择《Netkiller Architect 手札》地址 http://www.netkiller.cn/architect/ 接下来几周的话题是数据库安...

    netkiller old
  • Mysql配置文件 扩展详细配置(下)

    避免MySQL的外部锁定,减少出错几率增强稳定性。 5以前版本skip-locking,新版本skip-external-locking

    陈不成i
  • 你知道MySQL与MariaDB对子查询中order by的处理的差异吗?

    02-23无意中在在论坛看到一个帖;具体的问题大概就是MySQL与MariaDB对子查询中order by的查询结果不一样;

    SEian.G

扫码关注云+社区

领取腾讯云代金券