该有的没有:几种被悄悄藏起来的数据

这阵子在几个后台系统里反复遇到同一类事:数据明明该有,页面上就是看不到,接口还不报错,一路返回 200。折腾下来发现,这类问题的根子很像,都是"没有"被悄悄藏起来了。这里把我碰到的几次放一起记一下。先说好,有的是我看代码推出来的,没在现场验证,用到的地方我会直说。

同步了,账号就是没新增

上游用户接口里明明有个账号,状态也正常,本地用户管理页按登录名一搜,"暂无数据"。按同步规则,上游有、本地没有,应该新增一条,可现场就是没新增。

我先怀疑状态过滤,翻了代码发现不是,状态只决定新账号启用还是停用,不决定同不同步。后来想到软删除:后台删用户其实只是把删除标记改成"已删除",数据还在库里。用户列表的查询带着"没删除"的条件,软删除的账号页面上搜不到,看着就像"本地没有"。可同步用的那条查询没带这个条件,它能看到这个同名的已删除账号,一看有同名的就直接跳过了,既不恢复也不新建。

一边觉得"没有",一边觉得"有",两边对"存在"的定义不一样。

不过这只是看代码得出来的,我没拿到现场库里的查询结果,所以只能说最有可能。另外两种可能也没排除:同步任务可能根本没跑成功(接口立刻回"已提交",失败只写日志,前台看不到),或者现场跑的包比手头的代码旧。真要查就三步:直接查库(别带删除标记条件)、看同步日志、核对线上包的版本。

软删除和物理删除,到底选哪个

这事顺带暴露了另一个问题:后台是软删除,同步里又有物理删除,两边不统一。后来决定统一成物理删除,但改之前得想清楚一个后果:以前管理员在后台删掉一个上游还存在的账号,它就不会再被同步回来;改成物理删除后,手删完下次同步又会把它按初始密码、空角色建出来,停用也拦不住,因为同步会拿上游状态覆盖本地。也就是说,本地没法再屏蔽一个上游还存在的账号了。

这不算 bug,是个取舍,要看业务上还要不要这个能力。另外几点也是看代码和审查得出的,没部署没跑过:库里有没有外键得去线上看;老的软删除记录还在,同名的还会被跳过,得一次性清理;后台删用户也不会踢掉在线会话。

传错参数,接口返回空数组

有个按"时间加要素"查数据的接口,前端想一次选多个要素,就把几个值用逗号拼在同一个参数里,结果拿到空数组。传个不认识的值,也是空数组,不报错。看源码,要素参数只做单值精确匹配,匹配不上就返回空列表,没有任何提示,大小写也得完全一致。

前端想要多个要素,只能一个要素调一次;接口说明里要写清楚这几点。更根本的是服务端对不认识的值直接返回参数错误,别让"没数据"和"参数错了"长得一样。

编译通过了,功能却没了

有一批老接口从旧工程里恢复回来,编译和测试都过了,接口也都在。但我实测其中一个,请求返回 200,内容却是空数组。

查下来:原来的代码用 File 的方式去读打在 jar 包里的一个 CSV。老工程是 WAR 部署,这样读没问题;现在是可执行 JAR,jar 里的资源不是磁盘上的真实文件,用 File 路径根本读不到,代码又没报错,悄悄返回了空。读 classpath 里的资源要用输入流,比如 getResourceAsStream,别拿路径当文件。

这次我只实测了这一个接口,别的接口有没有类似问题,我不能打包票,得挨个测。"编译通过"只能说明语法没问题,不能说明原来的功能还能用。

Excel 合并单元格也会藏东西

这个跟代码无关,是份数据清单。"是否已接入"那一列在好多行上是合并单元格,结果有几行其实没有映射、也没有端到端证据,因为合并,读出来全继承了组首行的"已接入",看着像都接好了。

处理办法是把受影响的区间拆开合并,先把组首的值填回每一行,再按证据逐行更新状态,其他列的合并、字体、列宽都不动,改之前先备份。经验就是:合并单元格拿来排版可以,别拿来存逐行的状态。

小结

这几次的共同点是:问题出在你没盯着的那个地方,而且系统还很"配合"地返回了一个看着正常的结果。以后碰到"该有的没有",我会先问自己三件事:

  1. 这条数据在库里到底在不在,不带任何过滤条件查一下。
  2. 不同代码路径对"存在"的定义是不是一样。
  3. 失败会不会被吞掉,有没有只写日志、前台看不到的地方。

posted on 2026-11-02 10:01  因n而在  阅读(13)  评论(0)    收藏  举报

导航