NEVER
不使用事務,如果當前事務存在,則拋出例外
驗證:
@Service public class PrService { @Autowired PrDao dao; @Transactional public void savea() { dao.a();//保存第一條資料 saveb(); } @Transactional(propagation = Propagation.NEVER) private void saveb() { dao.b();//保存第二條資料 int i=1/0; } }
寫一個controller呼叫這個savea方法,頁面看到的是/ by zero,資料庫中兩條資料都沒有插入進去,都回滾了,照說設定了Propagation.NEVER,應該saveb方法根本執行不了,報never的錯,為什么執行了呢?
因為是直接呼叫的saveb(),不是從代理物件上呼叫的方法,改成這樣:
@Service public class PrService { @Autowired PrDao dao; @Autowired PrService prService; @Transactional public void savea() { dao.a();//保存第一條資料 prService.saveb(); } @Transactional(propagation = Propagation.NEVER) private void saveb() { dao.b();//保存第二條資料 int i=1/0; } }
注意這里是 prService.saveb()和前面不同,但是居然在 dao.b(); 這一行報了一個空指標的錯誤,這就詭異了,這個dao明明在上面的savea方法里面還有值的,你知道是為什么嗎?
原來saveb方法的修飾符是private,導致代理物件無法繼承這個方法,改成public
public void saveb()
再次測驗,看到期待的報錯了:
Existing transaction found for transaction marked with propagation 'never'
MANDATORY
當前存在事務,則加入當前事務,如果當前事務不存在,則拋出例外,
這里把MANDATORY放在saveb方法上,就要把savea方法上的transactional注解去掉,才能看到報錯,
@Service public class PrService { @Autowired PrDao dao; @Autowired PrService prService; public void savea() { dao.a();//保存第一條資料 prService.saveb(); } @Transactional(propagation = Propagation.MANDATORY) public void saveb() { dao.b();//保存第二條資料 } }
或者直接把MANDATORY放在a方法上也會報錯:
@Service public class PrService { @Transactional(propagation = Propagation.MANDATORY) public void savea() { } }
報錯如下
No existing transaction found for transaction marked with propagation 'mandatory'
REQUIRES_NEW
創建一個新事務,如果存在當前事務,則掛起該事務,
可以理解為設定事務傳播型別為REQUIRES_NEW的方法,在執行時,不論當前是否存在事務,總是會新建一個事務,
現在寫一個demo驗證,savea方法呼叫saveb方法,希望saveb方法里面例外了且事務回滾,savea方法里面不回滾
下面驗證:
同樣為了在避免事務失效,在代理物件上呼叫方法,將被呼叫的方法放到一個單獨的類中:
@Service public class PrService { @Autowired PrDao dao; @Autowired SaveBService saveBService; @Transactional public void savea() { dao.a();//插入第一條資料 saveBService.saveb(); } }
@Service public class SaveBService { @Autowired PrDao dao; @Transactional(propagation = Propagation.REQUIRES_NEW) public void saveb() { dao.b();//插入第二條資料 int i = 1/0; } }
這里PrService的savea方法呼叫SaveBService的saveb方法,寫一個controller訪問savea方法,頁面看到一個例外 / by zero,再檢查資料庫,兩條資料都有沒有插入進去,這是為什么呢?看上去第二個方法已經寫到獨立的類中了,
原來是因為saveb方法拋出的例外savea方法沒有捕獲,又拋出去了,當然要回滾了,寫個try catch就行:
@Transactional public void savea() { dao.a();//插入第一條資料 try { saveBService.saveb(); }catch (Exception e) { System.out.println("some error"); } }
再次測驗,第二條資料沒有插入,第一條資料插入到資料庫了,頁面也看不到報錯了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/551899.html
標籤:其他
下一篇:返回列表
