数据库-事故
背景
下单后,这里就会创建一个订单,这里的订单涉及到几个状态,订单创建,订单支付,订单服务中,完成, 订单完成。
用户在平台下单,首先当然需要填写一些信息,然后点击提交表单,提交后,就会跳转到一个支付页面,同时在支付页面也会有一个支付截止时间,
在这个截止时间内完成支付,订单状态就会进入到订单支付的状态,这个截止时间字段,对应数据表就用 endTime 表示,然后 endTime = createTime + 30 min 。
最近需要添加一个新的功能,就是能够支持自动退款的操作。
要求如果处于服务中的订单,要是 30 天没有提交完成的信息,那么就会给用户自动退款。
这个时候,就可以继续复用上面提到的 endTime,只需要设置一下endTime = endTime + 30 Day 。
通过写一个定时器,每隔几分钟查询订单表,判断是否有处于服务中的订单,并且 endTime 小于当前时间的,如果查询到了的话,就说明这个订单已经超过 30 天的服务周期,那么就执行退款流程。
这个流程上其实是没有问题的,出问题的是在一些历史的订单,因为对于一些历史处于服务中的订单,它的endTime 还是支付截止时间,而不是服务截止时间,即 endTime = createTime + 30 min。
所以在自动退款功能上线后,会把历史服务中的订单也扫描出来,然后执行退款操作,但是此时退款操作并没有完成,而是失败了,
因为写的部分逻辑对旧订单没有适配,从而触发了写的兜底的错误报警,造成所有退款操作都被回滚了。
事故复盘
第一时间先定位到异常代码,然后进行解决。
其实通过上述的描述,我们也可以发现根本的问题,即对于一些历史订单处理上出现问题,
这个时候,需要做的就是通过对数据库进行刷数操作,把历史订单的 endTime 增加 30 天,比如执行这样一个SQL语句:
UPDATE order SET end_time = DATE_ADD(create_time, INTERVAL 30 DAY) WHERE STATUS="服务中"
同时在进行订单状态的变更时,
如果该状态不需要使用到 end_time 时,那么需要及时将其清空,
而不能让其存储在数据库中,这样也可以避免以后可能再次发生。
order.endTime = NULL;
order.updateById();
这次事故的发生没有认真观察到之前 end_time 埋下的祸根。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能