记录在测试时出现的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服务器和本地时间不一致的问题;