記一次 @Transactional不生效的問題
阿新 • • 發佈:2019-02-09
今天寫程式碼的時候有一個service需要用到事務,故使用@Transactional註解
@Transactional
Map<String, Object> joinTeam(Long teamId, Long userId) throws Exception;
這裡丟擲自己定義的異常來實現事務回滾
介面實現類方法如下
public Map<String, Object> joinTeam(Long teamId, Long userId) throws Exception {
Map<String, Object> result = new HashMap<>();
Team team = teamService.getTeamById(teamId);
//新增組隊成員
TeamMember member = new TeamMember();
member.setUserId(userId);
member.setTeamId(teamId);
teamMemberDao.saveTeamMember(member);
//更新組隊人數
team.setCurrentSignup(team.getCurrentSignup() + 1 );
Long count = teamService.updateTeamCurrentSignup(team);
int i = 0;
while (count == 0) {
if (i >= 3) {
throw new BaseException(BaseException.OPTIMISTIC_LOCK);
}
team = teamService.getTeamById(teamId);
team.setCurrentSignup(team.getCurrentSignup() + 1 );
count = teamService.updateTeamCurrentSignup(team);
i++;
}
result.put("success", true);
result.put("message", "加入成功!");
throw new Exception(BaseException.OPTIMISTIC_LOCK);
}
teamMemberDao.saveTeamMember(member) 與 count = teamService.updateTeamCurrentSignup(team) 、兩個修改庫操作,需要 teamService.updateTeamCurrentSignup(team) 拋異常來控制 teamMemberDao.saveTeamMember(member) 的資料回滾
但是結尾拋異常資料並不回滾,很是糟心。
於是檢視Spring的Transactional的API文件,發現下面這段:
If no rules are relevant to the exception, it will be treated like DefaultTransactionAttribute (rolling back on runtime exceptions).
所以Transactional預設異常回滾是runtimeexcetion才回滾
excetion是所有異常的總稱。
而runtimeexcetion是具體的某一個異常。
所以得將Transactional設定回滾異常為excetion
故將介面修改如下,這次再拋自定義異常就會回滾了
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
Map<String, Object> joinTeam(Long teamId, Long userId) throws Exception;