人生苦短,不如养狗
一、问题现场
趁着这几天过节,复盘了一下去年的一些历史遗留问题,其中有这样一个关于数据库的小问题让我忍不住翻出来又回味了一下,下面就让我们一起品味品味。
首先,先来看下问题现场,操作数据库的执行流程如下图:
这里对原有的业务逻辑进行简化,简化后的代码实现如下:
public void finishSubTask(SubTask subTask){
// 进行子任务状态更新
subTaskService.updateFinish(subTask);
// 根据主任务id查询正在运行中的任务
int runningSubTaskNum = subTaskService.countRunning(subTask.getTaskId);
// 如果当前运行中任务为空,则终止主任务
if (runningSubTaskNum == 0) {
taskService.updateFinish(subTask.getTaskId);
}
}
乍一看好像逻辑和代码没有什么问题,但是在实际运行过程中有时会出现查询语句查出来的结果集是更新前的结果集,就好像更新没有生效或者“丢失”了,导致没有成功将对应的主任务终止。
二、追根溯源
在开始查案之前先说一下环境情况,MySQL版本为5.6(阿里云高可用版本,即一主一备,事务隔离级别为读已