1. 程式人生 > >記一次 @Transactional不生效的問題

記一次 @Transactional不生效的問題

今天寫程式碼的時候有一個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;