记录在测试时出现的mysql问题。
问题描述
摘要状态项目,项目的主要内容是更新表中商品入驿站的入库、上架和签收状态,然后在手机客户端会查询表来展现商品的状态。
这次重构项目,在自测完成后交给测试测试,测试用手机客户端来测试。
在测试时发现在做了入库后,更新上架操作时却始终更新不了表的状态。
问题分析
这次测试是在测试环境进行测试的。
查看打印的日志
分析日志,并没有报错。而且自测时这个sql也能正常更新表。
也就是说,这个sql是没有问题的,只不过update更新条数为0。那么就需要分析什么原因导致sql无法正常更新。
分析sql
查看代码中相关的代码,mybatis的sql:
UPDATE digest SET rack_time = #{opTime}, rack_no = #{rackNo, jdbcType=VARCHAR}, STATUS = ( CASE WHEN STATUS & lt;#{status} THEN #{status} ELSE status END), phone = ( CASE WHEN phone IS NULL OR phone = '' THEN #{phone, jdbcType=VARCHAR} ELSE phone END), reserve3 = #{reserve3, jdbcType=VARCHAR} , spare2 = #{desCount, jdbcType=VARCHAR} WHERE log_code = #{logCode} AND no = #{no} AND code = #{code} AND create_time > #{limitTime} AND create_time & lt;= NOW()
复制代码
将sql的where约束条件拿出来select执行看是否可以查到:
SELECT FROM t_exp_station_digest WHERE log_code = '2120' AND no = '194664943946564' AND code = '48303' AND create_time > '2021-03-17 16:01:16' AND create_time <= Now()
复制代码
发现可以查得到。
本地代码复现问题
让测试用客户端测了多次,发现这个问题每次都能复现出现。那么,这个问题就不是偶发性的。
在本地运行代码debug测试:重新运行一遍,发现的确可以没有正常更新状态。
然后又等了一会,查看这个sql的执行value情况,却发现这条sql执行成功了,更新条数为1。
为什么会刚开始没有执行成功,过了一会就执行成功了?
查看sql会发现这条sql唯一的变量是Now(),也就是当前的时间。
那么分析下来,执行不到就说明表中的create_time大于当前的时间。
但是按理说不应该这样,获取的Now()就是当前时间,为什么会大于表中的create_time字段的值呢?
那么就要知道create_time是从哪里来的?
这个是从客户端传来的,然后插入到表中。那么就是客户端的时间要大于mysql服务器的时间。这两个是有时间差的。
验证手机客户端和mysql服务器时间问题
在mysql服务器查看当前时间:
select now();
复制代码
查看手机客户端的时间,发现客户端时间比mysql服务器早40s。所以在更新时,sql没有在执行的范围内。
为什么自测就没有问题?
是因为在测试数据库时直接通过自写一个接口来测试的,数据也是自己造的。所以没有出现这个问题。
解决办法
去除掉create_time的小于等于这个约束条件即可。
复盘
- 在测试环境测试时,会出现mysql服务器和本地时间不一致的问题;