记一次生产事故 - 多线程修改数据库问题

一,缘由


有三个日期,昨日,今日,下一日
有两个修改入口
第一个,根据今日修改下一日时间
第二个,每日定时触发00过后,把今日赋值给昨日,下一日赋值给今日,或得下一自然日赋值给下一日。

原本数据应该是
 

时间 昨日 今日 下一日 
12 11     12 13
13 12 13 14    
14     13 14     15

但数据却是这样的
 

时间 昨日 今日 下一日 
12 11     12 13
13 13 14     14    
14     14     15 15

二,查找问题


 架构是双主双活,根据日志查询出问题如下:
第二个修改入口只交换昨日和今日数据
定时触发后,同时执行

A点修改13日的数据
 

时间 昨日 今日 下一日 
12 11     12 13


改为
 

时间 昨日 今日 下一日 
13 12 13 14    

因为是多条数据,有前后误差
B点修改时得到的数据已修改
 

时间 昨日 今日 下一日 
13 12 13 14    


改为

时间 昨日 今日 下一日 
13 13 14     14    


 

三,解决问题


方案一,单机执行定时任务
单机执行确实能解决当下问题,但失去了双活的优势,少了高可用性,一旦执行任务的节点挂掉,影响业务进行


方案二,数据库修改加锁
由于是两个入口进行修改,可在A点入口二的执行时加行锁,并在入口一解锁。在考虑到复杂程度和不确定后(入口一由调用方执行,会受到其成员的影响),决定放弃该方案


方案三,执行update操作优化
修改操作添加今日=昨日条件,一旦数据修改,说明该修改已执行,跳过,否则则进行修改。


 

猜你喜欢

转载自blog.csdn.net/qq_39308071/article/details/111309723