项目场景:
记录一次后台接口开发中遇到的问题
1、在移动端跳转H5页面请求后台接口
2、开发环境不报错
3、接口是一个查询接口,其中的数据每十分钟更新一次,更新逻辑是先删除表里面的数据,再进行数据统计,最后新增到表里
4、每十分钟结束时,会进行更新操作,操作窗口时间约5-10秒,这段时间内进行查询时,页面报错
问题描述
开发环境不报错,正常运行,但部署到生产环境时出现大串代码提示错误
数据查询过程中会报数据库查询错误
Cause:com.microsoft.sglserveridbc.SQLServerException: 从数据类型 varchar 转换为 numeric 时出错

APP 中接收数据代码:
@Override
public ParkingLotExceptionsVO selectExceptions(@Validated TimeInput ti) {
return parkingLotMapper.selectExceptions(ti);
}
数据库查询语句是
<select id="selectTrafficFlow"
resultType="com.chngalaxy.wholemarketing.domain.model.parkingLot.TrafficFlowVO">
SELECT tmp.zcll trafficFlowTotal,
tmp.rcclbq trafficFlowEnter,
(CASE
WHEN tmp.rcclbq = '0' AND tmp.rcclsq = '0' THEN CONCAT('环比', 0, '%')
WHEN tmp.rcclbq != '0' AND tmp.rcclsq = '0' THEN CONCAT('环比',
CONVERT(DECIMAL(20, 2), CONVERT(DECIMAL(20, 2), tmp.rcclbq)) *
100)
WHEN (tmp.rcclbq = '0' AND tmp.rcclsq != '0') OR (tmp.rcclbq != '0' AND tmp.rcclsq != '0') THEN CONCAT(
'环比', CONVERT(DECIMAL(20, 2), (
(CONVERT(DECIMAL(20, 2), tmp.rcclbq) - CONVERT(DECIMAL(20, 2), tmp.rcclsq)) /
CONVERT(DECIMAL(20, 2), tmp.rcclsq))) * 100, '%')
ELSE '' END
) AS trafficFlowEnterChain,
tmp.ccclbq trafficFlowExit,
(CASE
WHEN tmp.ccclbq = '0' AND tmp.ccclsq = '0' THEN CONCAT('环比', 0, '%')
WHEN tmp.ccclbq != '0' AND tmp.ccclsq = '0' THEN CONCAT('环比',
CONVERT(DECIMAL(20, 2), CONVERT(DECIMAL(20, 2), tmp.ccclbq)) *
100)
WHEN (tmp.ccclbq = '0' AND tmp.ccclsq != '0') OR (tmp.ccclbq != '0' AND tmp.ccclsq != '0') THEN CONCAT(
'环比', CONVERT(DECIMAL(20, 2), (
(CONVERT(DECIMAL(20, 2), tmp.ccclbq) - CONVERT(DECIMAL(20, 2), tmp.ccclsq)) /
CONVERT(DECIMAL(20, 2), tmp.ccclsq))) * 100, '%')
ELSE '' END) AS trafficFlowExitChain
FROM (SELECT MAX(IIF(t.id = 1, t.num, '')) zcll,
MAX(IIF(t.id = 2, t.num, '')) rcclbq,
MAX(IIF(t.id = 3, t.num, '')) rcclsq,
MAX(IIF(t.id = 4, t.num, '')) ccclbq,
MAX(IIF(t.id = 5, t.num, '')) ccclsq
FROM bi_tc_rate t
WHERE t.id IN (1, 2, 3, 4, 5)
AND SUBSTRING(month, 1, 4) = #{year}
AND SUBSTRING(month, 5, 2) = #{month}) tmp
</select>
原因分析:
经测试后发现每次报错是处于更新到窗口时间,在这段时间进行查询时,由于当前查询条件没有筛选到数据(比如2023年3月查询,查询出来的数据已经被删除,正在等待更新中)
由于更新逻辑没有进行事务控制处理,查出来的数据为空,空的数据后来又进行了一次从数据类型 varchar 转换为 numeric 的格式转换,所以前端会返回SQL转换的错误信息
解决方案:
将业务逻辑层的接口查询语句进行try-catch自定义异常捕获,若查询不到当前数据,这直接抛出自定义异常信息
逻辑层代码如下:
@Override
public ParkingLotExceptionsVO selectExceptions(@Validated TimeInput ti) {
ParkingLotExceptionsVO vo;
try {
vo = parkingLotMapper.selectExceptions(ti);
} catch (Exception e) {
throw new BusinessException(ExceptionCode.PARKING_LOT_ERROR, "数据同步中,请刷新重试");
}
return vo;
}
问题解决后的效果展示:

顺便如果以后再次遇到这样的场景,需要将数据更新的方式进行事务处理,在更新的窗口时间内进行查询也不会报错,或者先将数据进行统计,再进行删除和新增行数据
在移动端调用后台接口查询数据时,遇到数据库查询错误,原因是数据更新过程中未使用事务控制,导致查询到空数据并在转换数据类型时出错。通过在业务逻辑层添加异常捕获并抛出自定义异常解决了问题。建议改进更新逻辑,采用事务处理以确保查询一致性。
3050

被折叠的 条评论
为什么被折叠?



