啟用事務配置
使用@Transaction注解方式配置良漱,
在啟動主類添加注解:@EnableTransactionManagement
在對應的方法上或者類上加上@Transaction就會自動接入到spring的事物中飘弧,讓spring管理逛尚。
Springboot中使用 @Transaction注解不生效的情況
- 情況1:
遇到非檢測異常時揍移,事務不開啟狸捅,也無法回滾兴枯。
原因:因為Spring的默認的事務規(guī)則是遇到運行異常(RuntimeException)和程序錯誤(Error)才會回滾汗盘。如果想針對非檢測異常進行事務回滾,可以在@Transactional 注解里使用rollbackFor 屬性明確指定異常猾蒂。
@Override
@Transactional
public void save2(ArBill bill) throws SQLTimeoutException {
ArBill save = billRepository.save(bill);
System.out.println(save.getId());
if ("01".equals(save.getBillStatus())) {
throw new SQLTimeoutException("lala");
}
}
@Transactional
public void save3(ArBill bill) {
ArBill save = billRepository.save(bill);
System.out.println(save.getId());
if ("01".equals(save.getBillStatus())) {
throw new ArBillException("lala");
}
}
- 情況2: 在業(yè)務層捕捉異常后均唉,發(fā)現(xiàn)事務不生效。
原因:在業(yè)務層手工捕捉并處理了異常(try…catch)等于把異扯遣ぃ“吃”掉了舔箭,Spring自然不知道這里有錯,更不會主動去回滾數(shù)據蚊逢。推薦做法是在業(yè)務層統(tǒng)一拋出異常层扶,然后在控制層統(tǒng)一處理
- 情況3 :注解到protected可見度的方法上,事務不生效
原因:@Transactional 注解應該只被應用到 public 可見度的方法上烙荷。 如果你在 protected镜会、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不會報錯终抽, 但是這個被注解的方法將不會展示已配置的事務設置戳表。
- 情況4
默認情況下,只有來自外部的方法調用才會被AOP代理捕獲昼伴,也就是匾旭,類內部方法調用本類內部的其他方法并不會引起事務行為,即使被調用方法使用
@Transactional注解進行修飾圃郊。
ps :
需要注意的是調用的方法是否標記為@Transaction
A:如果標記了, 也是處于spring管理下的,那么也是生效的,
B:如果是一個普通方法,調用標記了@Transaction事務注解, 那么不生效.
@Override
public void save8(ArBill bill) {
save8son(bill);
}
@Transactional
private void save8son(ArBill bill){
arBillTestRepository.deleteByBillIda("123");
}
- 情況 5 : 數(shù)據庫配置可能會影響事務
例如 Mysql 數(shù)據庫引擎 MyISAM 和 innodbj
MyISAM存儲引擎的特點是:表級鎖价涝、不支持事務和全文索引
InnoDB存儲引擎的特點是:行級鎖、事務安全(ACID兼容)持舆、支持外鍵查詢表的引擎
show table status飒泻;
80
@Transactional 注解的屬性介紹
value 和 transactionManager 屬性
它們兩個是一樣的意思鞭光。當配置了多個事務管理器時,可以使用該屬性指定選擇哪個事務管理器泞遗。
propagation 屬性
事務的傳播行為惰许,默認值為 Propagation.REQUIRED。
可選的值有:
-
Propagation.REQUIRED
如果當前存在事務史辙,則加入該事務汹买,如果當前不存在事務,則創(chuàng)建一個新的事務聊倔。
-
Propagation.SUPPORTS
如果當前存在事務晦毙,則加入該事務;如果當前不存在事務耙蔑,則以非事務的方式繼續(xù)運行见妒。
-
Propagation.MANDATORY
如果當前存在事務,則加入該事務甸陌;如果當前不存在事務须揣,則拋出異常。
-
Propagation.REQUIRES_NEW
重新創(chuàng)建一個新的事務钱豁,如果當前存在事務耻卡,暫停當前的事務。
-
Propagation.NOT_SUPPORTED
以非事務的方式運行牲尺,如果當前存在事務卵酪,暫停當前的事務。
-
Propagation.NEVER
以非事務的方式運行谤碳,如果當前存在事務溃卡,則拋出異常。
-
Propagation.NESTED
和 Propagation.REQUIRED 效果一樣蜒简。
isolation 屬性
事務的隔離級別瘸羡,默認值為 Isolation.DEFAULT。
- DEFAULT :表示使用底層數(shù)據庫的默認隔離級別臭蚁。對大部分數(shù)據庫而言最铁,通常這值就是: READ_COMMITTED 讯赏。
- READ_UNCOMMITTED :該隔離級別表示一個事務可以讀取另一個事務修改但還沒有提交的數(shù)據垮兑。該級別不能防止臟讀和不可重復讀,因此很少使用該隔離級別漱挎。
- READ_COMMITTED :該隔離級別表示一個事務只能讀取另一個事務已經提交的數(shù)據系枪。該級別可以防止臟讀,這也是大多數(shù)情況下的推薦值磕谅。
- REPEATABLE_READ :該隔離級別表示一個事務在整個過程中可以多次重復執(zhí)行某個查詢私爷,并且每次返回的記錄都相同雾棺。即使在多次查詢之間有新增的數(shù)據滿足該查詢,這些新增的記錄也會被忽略衬浑。該級別可以防止臟讀和不可重復讀捌浩。
- SERIALIZABLE :所有的事務依次逐個執(zhí)行,這樣事務之間就完全不可能產生干擾工秩,也就是說尸饺,該級別可以防止臟讀、不可重復讀以及幻讀助币。但是這將嚴重影響程序的性能浪听。通常情況下也不會用到該級別。
timeout 屬性
事務的超時時間眉菱,默認值為-1迹栓。如果超過該時間限制但事務還沒有完成,則自動回滾事務俭缓。
readOnly 屬性
指定事務是否為只讀事務克伊,默認值為 false;為了忽略那些不需要事務的方法尔崔,比如讀取數(shù)據答毫,可以設置 read-only 為 true。
rollbackFor 屬性
用于指定能夠觸發(fā)事務回滾的異常類型季春,可以指定多個異常類型洗搂。
noRollbackFor 屬性
拋出指定的異常類型,不回滾事務载弄,也可以指定多個異常類型耘拇。