目标逻辑:
背景:对3条(多条)数据先进行审核通过、后发奖励操作。发奖动作不应影响审核并且实时性不高,所以在审核通过之后开启新线程进行发奖操作。
预期:数据状态有auditStatus(审核状态)与issueStatus(发奖状态),3条(多条)数据状态均从auditStatus更新为PASS(审核通过),issueStatus更新为SUCCESS(发放成功)或者FAIL(发放失败)。
做法:审核通过后开启新线程进行发放操作。代码的结构大致上是这样的
@Transactional(rollbackFor=Exception.class)
public void resolve(List<SettlementDTO> dtos){
for(SettlementDTO dto : dtos){
doSomething(dto);
pass(dto);
}
}
public void pass(final SettlementDTO dto){
dto.setAuditStatus("PASS");
update(dto);
dto.setVersion(dto.getVersion() + 1l);
new Thread(new Runnable() {
@Override
public void run() {
doSomething(dto);
dto.setIssueStatus("SUCCESS");
update(dto);
}
}).start();
}
实际行为:3条(多条)数据审核通过,有时候1条有时候2条数据发放成功。
分析:
拿一条更新成功举例,
起初以为是多线程引起的线程管理的局部变量被其他线程篡改。于是把代码改成了这样,保证了每个线程改的是自己的局部变量。
&n