mysql datetime类型字段存入时间多了1秒导致的问题

一、问题描述

商城系统今天上线了一个功能,用户在商城中点击商品详情页的去购买按钮时,如果商品是有代金券优惠活动的商品,则会先领券后计算商品金额。 这里面涉及到两步操作:调用领券接口,领券成功后,调用计算接口(计算商品价格接口),计算接口内部会调用代金券查券接口。遇到问题是,发券后,立即调用代金券查询代金券,查询不到刚发的代金券,停几秒中再去查,就可以查到,这种情况大概率会复现。

很奇怪的问题,代金券系统已经很久没有修改过了,线上也未爆出过发了代金券而查询不到的情况。

二、问题排查


一开始以为是数据库主从延迟导致的,把代金券查询接口日志打开,发现dao从库中查询时是可以查到刚发送的券,但是进行规则过滤后,代金券被过滤了,添加详细的日志,发现代金券是被有效期校验给过滤了。

代金券的有效期校验是:当前时间 >= 代金券创建时间 and 当前时间 <= 代金券结束时间

代金券有效期一般都是从发券时间开始,到发券时间+7天,因此当前时间必然<代金券结束时间,那么就是当前时间小于创建时间导致过滤,这就更奇怪了,发券在前,查询在后,查询时,系统时间应该是大于代金券创建时间的,为什么会被过滤呢。

查看数据库记录,发现一个奇怪的问题,代金券createtime居然比updatetime多了1s:

createTime updateTime
2021-07-01 14:18:42 2021-07-01 14:18:41


心理隐约感觉找到了方向。继续查看代金系统的日志,发现创建日志打印时间为:2021-07-01 14:18:41.529, 而查询代金券的时间为2021-07-01 14:18:41.611。
这大概就找到问题了,createTime入库时间比系统时间多了1秒,导致2021-07-01 14:18:41.611 < 2021-07-01 14:18:42。那么为什么入库时间会多1秒呢?

查看代金券createTime设值的代码:

setCreateTime(new Date());

取的是当前系统时间,而updateTime其值不是由java代码设置的,而是设置了默认值,也就时入库时,会取mysql current time。
看下createtime和updatetime的sql定义:

`create_time` datetime(0)  DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
  `last_update_time` timestamp(0)  DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '最后更新时间',

发现两个字段的类型居然不一致,createTime是datetime(0)类型,表示时间会精确到秒,而updateTime是timestamp(0)。

百度一番,发现这居然是mysql的一个bug, 当时间字段类型为datetime时,如果时间毫秒数小于500时,向下舍,如果大于等于500时向上加1秒,也就是:

2021-07-01 14:18:41.400 会存为2021-07-01 14:18:41
2021-07-01 14:18:41.591 会存为2021-07-01 14:18:42

参考:
https://wuxiangknow.cn/mysql/%E5%85%B3%E4%BA%8EMysql5.7%E5%AD%98%E5%82%A8%E6%97%B6%E9%97%B4%E5%A4%9A%E4%B8%80%E7%A7%92%E7%9A%84BUG/


线上之所以一直未爆出这个问题,主要是没有这种领券后,在极短时间(500ms内)就去查券的场景,而商城这个场景是自动发券自动查,间隔时间基本上100ms以内,才爆出这个问题。

三、问题解决

解决办法有3个:

  1. 查询判断时,取当前时间时,加1s
  2. 存datetime类型的字段时,对Date类型的值进行处理,将毫秒置为000,比如2021-07-01 14:18:41.400 设置为2021-07-01 14:18:41.000
  3. 将mysql时间类型改为datetime(3),或者timestamp类型。

推荐第二种,因为第1种并没有解决根本问题,存入的数据本身就是错的,保不齐其他地方也会有日期判断的地方,如果数据存入的就是错的,其他地方判断也会是错的。而第3种需要修改数据库字段类型,公司内对数据量大的表进行修改比较麻烦,而且时间精确到毫秒意义并不大,还会占用更多的空间,不如修改两行代码来的快捷。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容