宣告式事務不回滾@Transactional的避坑正確使用
在我們開發中很多時候都要用到事務,例如轉賬等等的操作,這些我就不多BB了,哈哈。
下面我要說的又是一個坑,也是宣告式事務不回滾的問題。重點來了 來了。。。。
@Transactional(rollbackFor = Exception.class) //一定要加 rollbackFor = Exception.class 引數,下面會說明原因:
如果你在寫程式碼時候和我一樣在類上或者在方法上加上@Transaction,就直接認為自己事務問題加好了。例如:
@Override @Transactional public void AddUserException() throws FileNotFoundException {}
這樣的設定其實是存在問題的,之前我也是認為這樣,我也想就這樣他會預設新增傳播屬性什麼的。下面我們實驗看看有什麼問題:
@Override
@Transactional
public void AddUserException() {
SysUserEntity user=new SysUserEntity();
user.setUniqueCode(UUIDGenerator.getUUID());
user.setUsername("測試Exception");
user.setPassword("我覺得我需要幾個關注的粉絲哈哈。");
user.setMobile("1095551903");
sysUserDao.insert(user);
int i=1/0;
}
實驗結果:
丟擲 / by zero,事務回滾成功
再次實驗:
@Override
@Transactional
public void AddUserException() throws FileNotFoundException {
SysUserEntity user=new SysUserEntity();
user.setUniqueCode(UUIDGenerator.getUUID());
user.setUsername("測試Exception");
user.setPassword("我覺得我需要幾個關注的粉絲哈哈。");
user.setMobile("1095551903");
sysUserDao.insert(user);
//int i=1/0;
FileInputStream fis = new FileInputStream("D://a.txt");
}
實驗結果:
丟擲異常java.io.FileNotFoundException,事務並未回滾
此時你腦袋是不是出現一句臥槽,難道我之前寫的。。。,哈哈哈哈快點回去改程式碼吧。
其實也並非都會有這種問題,這種問題出在你並沒有捕獲這個異常,直接向上丟擲,如果捕獲try catch 瞭然後又丟擲一個自定義異常之類的,就不會出現這個問題。
具體原因:當我們使用@Transaction 時預設為RuntimeException(也就是執行時異常)異常才會回滾。
簡單說下異常吧,異常分為檢查異常,和非檢查異常(也就是執行時異常)。
檢查異常例如IOException異常等,在你寫程式碼時編譯提示你必須try catch 或向上拋,反正就是必須處理。
而執行時異常,就是在執行時的產生異常(有點廢話啊,不過就是這個意思),例如/by zero異常。
所以當我們上面實驗丟擲java.io.FileNotFoundException檢查異常時導致了資料的不回滾。
說了這麼多,有點累了,不墨跡了,之前沒打算寫Demo想直接表述了的,後來今天突然發現我有一個粉絲了,哈哈哈哈哈所以寫了個Demo。
解決方法。這樣新增事務@Transactional(rollbackFor = Exception.class) 不管檢查異常還是非檢查異常都會回滾。如果感覺對你有用,算我沒白忙活。一起同行。