📢 本文由 gemini-2.5-flash 翻譯
事務
事務是一組操作的集合,它是一個不可分割的工作單位,這些操作要嘛同時成功,要嘛同時失敗。
操作:
- 開啟事務 (一組操作開始前,開啟事務):start transaction / begin
- 提交事務 (這組操作全部成功後,提交事務):commit
- 回滾事務 (中間任何一個操作出現例外,回滾事務):rollback
假設刪除部門後要繼續刪除該部門員工。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| @Service
public class DeptServiceImpl implements DeptService{
@Autowired
private DeptMapper deptMapper;
@Autowired
private EmpMapper empMapper;
@Override
public void delete(Integer id){
//1.刪除部門
deptMapper.delete(id);
// 假如這裡出現錯誤,只刪除了部門,沒刪除員工
//2.根據部門id,刪除部門下的員工資訊
empMapper.deleteByDetId(id);
}
}
|
如上所示,將會留下不存在部門的員工,造成了資料的不一致。
Spring 事務管理
註解:@Transactional,位置:Service 層方法、類別、介面上
作用:將當前方法交給 Spring 進行事務管理,方法執行前開啟事務;成功執行完畢提交事務;出現例外回滾事務。
上述方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| @Service
public class DeptServiceImpl implements DeptService{
@Autowired
private DeptMapper deptMapper;
@Autowired
private EmpMapper empMapper;
@Transactional // 交給Spring進行事務管理
@Override
public void delete(Integer id){
//1.刪除部門
deptMapper.delete(id);
//2.根據部門id,刪除部門下的員工資訊
empMapper.deleteByDetId(id);
}
}
|
同時可以開啟事務管理日誌。
1
2
3
4
| #Spring事務管理日誌
logging:
level:
org.springframework.jdbc.support.JdbcTransactionManager: debug
|
事務屬性 - 回滾
預設情況下,只有出現執行期例外 (RuntimeException) 才回滾事務,透過 rollbackFor 屬性可以控制出現何種例外類型時,回滾事務。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| @Service
public class DeptServiceImpl implements DeptService{
@Autowired
private DeptMapper deptMapper;
@Autowired
private EmpMapper empMapper;
// 所有例外都回滾
@Transactional(rollbackFor = Exception.class)
@Override
public void delete(Integer id){
//1.刪除部門
deptMapper.delete(id);
//2.根據部門id,刪除部門下的員工資訊
empMapper.deleteByDetId(id);
}
}
|
事務屬性 - 傳播行為
事務傳播行為是指當一個事務方法被另一個事務方法呼叫時,這個事務方法應該如何進行事務。
1
2
3
4
5
6
7
8
9
10
11
| @Transactional
public void a(){
// code
userServices.b();
// code
}
@Transactional
public void b(){
// code
}
|
上述 a 呼叫了 b,b 該如何進行事務,加入 a 的事務或者單獨開一個事務。
可以透過屬性 propagation 進行控制。
| 屬性值 | 描述 |
|---|
| REQUIRED (預設值) | 需要事務,有則加入,無則建立新事務 |
| REQUIRES_NEW | 需要事務,無論有無都建立新事務 |
| SUPPORTS | 支援事務,有則加入,無則在無事務狀態執行 |
| NOT_SUPPORTS | 不支援事務,有事務則暫停,在無事務下執行 |
| MANDATORY | 必須有事務,否則拋出例外 |
| NEVER | 必須無事務,否則拋出例外 |
使用範例
1
2
3
4
5
6
7
8
9
10
11
| @Transactional
public void a(){
// code
userServices.b();
// code
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void b(){
// code
}
|