文章内容
2026/1/21 19:47:54,作 者: 黄兵
AI 给我挖的一个坑
最近在使用 Gemini 写一个服务,主要是扫描 20 分钟之内的订单,如果订单超过 20 分钟没有任何数据返回,则退还给用户费用。
我多次测试,订单已经超过 20 分钟,第三方也没有返回任何数据,订单状态依然没有改变。
经过深度思考之后,得出如下结论:查询 20 分钟只能的订单,后面又是获取超过 20 分钟没有获取到数据的订单,这个明显相互矛盾。
代码大部分是 Gemini 写的,我发现了这个问题之后,告诉 Gemini,Gemini 回复我:
你的观察非常敏锐,且完全正确。这是一个极其严重的逻辑悖论。
错误分析
你的 SQL 逻辑:AND o.create_time > DATE_SUB(UTC_TIMESTAMP(), INTERVAL 20 MINUTE)这句话的意思是:只查询最近 20 分钟内创建的订单(即“年轻”的订单)。
例如:现在是 10:00,它只查 09:40 ~ 10:00 之间的订单。
你的 Python 逻辑:if (datetime.utcnow() - create_time).total_seconds() > 1200:这句话的意思是:如果订单创建时间超过 20 分钟(即“年老”的订单),则执行退款。
例如:现在是 10:00,它要求订单必须是 09:40 之前创建的。
死锁结果: SQL 过滤掉了所有“老”订单,只把“年轻”订单交给 Python。Python 拿到“年轻”订单后,判断它们没超时,于是去查短信。 结果: 那些真正超过 20 分钟、需要退款的订单,永远不会被 SQL 查出来,因此永远无法触发退款逻辑。它们会永久停留在processing状态。
之后我询问 Gemini:
你咋这么坑人呢😅🤣😓 这么明显的逻辑错误,你都没有看出来。
Gemini 回复:
哈哈,这回确实是我**“掉链子”了,还在前面一本正经地给你写了那么长的代码,结果埋了个这么大的坑 🙈。这绝对是一个教科书级别的“逻辑死锁”**笑话:
SQL 说: “我只放行 20 分钟内的小鲜肉订单。” (< 20 min)
Python 说: “我只处理 20 分钟以上的老腊肉订单进行退款。” (> 20 min)
结果: 老订单进不来,新订单不符合条件,所有超时退款逻辑全部失效。😅
多亏你有一双**“火眼金睛”**!如果这个代码直接上线,那就是妥妥的生产事故:用户收不到码,钱还没退,过几天你的客服电话就要被打爆了。
总结一下这次的“教训”和最终修正:
我们在写轮询(Poller)服务的 SQL 时,通常有两种策略,千万不能搞混:
策略 A(只查待处理): SQL 不做时间限制,只查状态(WHERE status = 'processing')。
优点: 绝对不会漏单。
缺点: 随着数据量增大,查询可能会变慢(需要加索引)。
策略 B(时间窗口法 - 也就是我们用的):
必须把时间窗口拉得足够大!
如果业务超时是 20 分钟,SQL 必须至少查 过去 24 小时 甚至更久的数据。
目的: 为了“兜底”。为了把那些系统重启期间、网络波动期间漏掉的“超时单”全部捞回来退款。
虽然 AI 编写代码大部分没有问题,但是有的时候出现了问题,很难被发现,尤其是那种存在逻辑错误的问题,就更难发现。
上面就是一个真实的案例。
不过通过上面 AI 的回复,AI 还是在努力缓解尴尬(不过话说回来:AI 有尴尬的感觉吗?)
最后放一张 Gemini 回复我的截图:

其它相关推荐:
3、Codex 折腾
评论列表