[英]Rollback in async method that calls another transactional method
我有一個非事務和異步方法,該方法調用同一服務的其他事務方法。
如果發生某些事情,我會捕獲異常,如果發生某些事情,我會保存錯誤,但回滾不起作用。
在此示例中,要調用播放器服務的保存方法,事務將保存播放器。
@Service
@Transactional(readOnly = true)
public class PlayerServiceImpl implements PlayerService {
@Inject
PlayerRepository playerRepository;
@Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public void save(PlayerEntity player) {
//more code here
playerRepository.save(player);
}
//other methods
}
我的其他服務:
@Service
public class TeamServiceImpl implements TeamService {
@Inject
TeamRepository teamRepository;
@Inject
MessageRepository messageRepository;
@Inject
ErrorRepository errorRepository;
@Inject
PlayerService playerService;
@Async("asyncExecutor")
@Override
public void saveWithPlayersAsync(TeamEntity team, User user) {
MessageEntity message = new MessageEntity();
try {
//I want rollback this if something wrong happens
this.savePlayersA(team);
this.savePlayersB(team);
message.setContent("Ok !");
} catch (TeamException e) {
//e.printStackTrace();
message.setContent("Fail !");
message.setUser(user)
//I save the error for audit
errorRepository.save(new Error("Fail", user.getCode()));
} finally {
//always save message for user than execute de function
messageRepository.save(message);
}
}
@Transactional(readOnly = false, rollbackFor = TeamException.class)
private void savePlayersA(TeamEntity team) throws TeamException {
PlayerEntity p1 = new PlayerEntity();
p1.setName("Name 1");
p1.setSurname("Surname 1");
p1.setTeam(team);
playerService.save(p1);
PlayerEntity p2 = new PlayerEntity();
p2.setName("Name 2");
p2.setSurname("Surname 2");
p2.setTeam(team);
playerService.save(p2);
}
@Transactional(readOnly = false, rollbackFor = TeamException.class)
private void savePlayersB(TeamEntity team) throws TeamException {
PlayerEntity p3 = new PlayerEntity();
p3.setName("Name 3");
p3.setSurname("Surname 3");
p3.setTeam(team);
playerService.save(p3);
PlayerEntity p4 = new PlayerEntity();
p4.setName("Name 4");
p4.setSurname("Surname 4");
p4.setTeam(team);
playerService.save(p4);
// here something happens and throw my custom exception
if (true) {
throw new TeamException("Fail!");
}
}
}
為什么不回滾? 我將異常類型放入rollbackFor中。
之所以不會回滾,是因為調用事務方法的異步方法在同一類中。 當使用@Transaction或@Async注釋方法時,注釋代碼由spring創建的代理處理。 當被注釋的方法在同一個類中時,代理無法捕獲對它們的調用以通過spring處理其他請求,因此該方法上的注釋是多余的。 您可以通過在單獨的類中使用savePlayer方法並在那里進行事務處理來實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.