1. 程式人生 > >宣告式事務不回滾@Transactional的避坑正確使用

宣告式事務不回滾@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) 不管檢查異常還是非檢查異常都會回滾。如果感覺對你有用,算我沒白忙活。一起同行。