记录一次因now()函数应用周期性查不到数据的问题

文章讲述了在测试环境中,由于数据库容器时间比实际时间晚8小时,导致使用now()函数的SQL查询失效。开发人员通过分析和排查,发现服务器时间设置对应用的影响,并强调了在编写SQL时考虑数据库兼容性和服务器时间同步的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题原因:

        查询sql使用了now()函数,测试环境数据库所在的容器日期不对,与实际时间晚8个小时。

问题背景描述:

        某天下午快要下班的时候,大概五点的样子,某个测试小哥在系统里点击用户注册功能注册后,一切数据都正常生成后,登录新注册的用户,发现这个用户的菜单都没查询到,然后反馈到,说这功能用户没菜单啊。然后对应的开发小哥说明儿再给看,结果到明天看的时候,这用户的菜单又查到了。然后开发小哥让他再观察观察,毕竟开发小哥本地开发环境是没有这个问题的。知道这个问题再次出现,引起了需求验收的注意,然后开发小哥静下心来一顿分析。

 分析过程:

        对查询菜单的代码逻辑进行一顿分析后,尝试了清理浏览器缓存、内存中间件缓存,问题依然出现。只能尝试对第三方jar进行反编译查看加日志了,对比本地开发环境与测试环境的日志,也没发现太多的不一样,直到恰巧不巧的时候,开发小哥在点击第三方系统的一个某个功能时,发现新注册的用户所属单位直接显示不出来了,这一现象引起了他的注意,然后尝试跟踪这个查询单位的接口逻辑,结果发现这个查询单位的sql里有用到一个过滤条件 A.client_id = '1004' and A.start_time <= now(), 拿着该sql在本地开发环境数据库能够查询出数据,但是拿到测试环境的数据库查询却查询不到数据,两个库里的数据是一致的前提。就在测试环境数据尝试去掉一些and条件,结果发现去掉A.startTime <= now()这个后,就能查询出来。这个时候看了A.start_time字段值是正常的,就开始怀疑now()了。就在两个环境的数据库分别执行select now() from dual;结果开发环境的查询值正常,测试环境的查询值比当前时间时间晚8个小时。以此断定数据库的时间配置是有问题的。然后走查查询菜单的代码逻辑,发现里面也存在查询单位按照A.startTime <= now()过滤的逻辑。以此更加确定,查询不出来就是这个时间导致的了。

 改动调整:

        开发小哥根据自己的分析结论,找测试小哥查看数据库服务器时间,然后测试小哥反馈服务器时间没问题啊,服务器命令查询也是正常的啊。然后让测试小哥直接在数据库里查询now(),结果他也觉得时间不对,就找运维小哥看了看,结果运维小哥反馈,这个数据库是docker镜像方式启动的,时间取决于容器,就查看容器时间,容器时间就是晚8个小时的,然后校正了容器时间,重启了数据库,让测试小哥直接在数据库里查询now()这次时间是对的了,就重启了测试环境的系统,再次登录新注册的用户,菜单就可以查询到了。这也刚好对上了,为啥下午五点查不出来,第二天早上一来就查出来了,第二天早上相隔都超过8个小时了,自然A.startTime <= now()满足了。

总结:

        在写sql时,还是尽量避开使用数据库特有的函数,数据库适配时兼容性不是很好一方面,也藏着一些暗坑,某些场景也影响性能。然后关于服务器时间这个,在应用所关联到的服务器尽量保证时间是同步的,这样可以避免一些奇怪的问题。然后就是关于一些奇怪的问题,大胆猜测勇于有目的性尝试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值