1.事情起始: 我们每个月要给商家进行出账,所以有定时任务去跑商家的订单和售后进行出账,这个功能已经上线很久了,代码执行多次都没问题,突然有一天,产品找我说出现bug了:
这时,去生产库查询重复的订单,发现大部分商家都出现了问题,有些商家的订单没问题,接下来就拷贝生产数据到开发环境,用生产分支的代码重新执行,发现没问题,但偏偏生产有问题,后面给订单号加上唯一索引
在生产重新跑了一遍,结果日志显示,报错原因都是重复的订单号,因为前面加了唯一索引约束了。这里至少证明不是代码bug引起的了:突然想起,公司最近加了数据库主从,原因就大概是主从延迟导致的,账单的业务大概如下:
while(true){
1. select * from order where bolsettement="n";//查询待结算的订单
2.处理订单信息,生成订单明细
3.更新订单状态为已结算 update order set bolsettement="y" where cod_order_id in(.....); //批量处理
}
由于主从默认主库执行写操作,从库执行读操作,假如上面更新订单状态要2s,那么主库执行完毕,立刻返回执行结果,此时从库同步主库需要2s,但我们的代码执行回到第1步,此时立刻查询从库,那么数据就不一致了,导致严重的问题
解决方案: 对于某些查询sql,也强制从主库去查询,由于我们用的是阿里云的数据库,所以他们的方案如下: