日常Bug排查-拋異常不回滾


日常Bug排查-拋異常不回滾

前言

日常Bug排查系列都是一些簡單Bug排查,筆者將在這里介紹一些排查Bug的簡單技巧,同時順便積累素材_

Bug現場

最近有人反映java應用操作數據庫的時候,拋異常不回滾。這還了得,不過筆者篤定肯定是用法的鍋,不然就全亂套了。所以筆者去Review他的代碼。

代碼片段

@Transacion(value="x") 
public void s1() throw MyException{ 
	update(1); 
	throwBusinessException();
 	update(2); 
} 

乍看上去沒啥問題。

思路

筆者用@Transaction注解也用了好幾年了,從來沒遇到過拋異常不回滾的情況。看他的用法也和筆者差不多呀?
然后筆者稍微思索了會,發現我寫的代碼和出問題的這一段稍稍有些不一樣。我是這么寫的:

@Transacion(value="transManager") 
public void s1(){ 
	update(1); 
 	update(2); 
} 

貌似我從來沒有在函數上加過throw MyException,難道是這段有問題?
翻看MyException代碼,發現它僅僅繼承了Exception。

class MyEception extends Exception {
}

好像就這點不一樣。而筆者自定義的Exception基本繼承了RuntimeException的。

翻下Spring源碼

按照這個思路,筆者去翻了下Spring的源碼,看下它在聲明式事務中的處理邏輯到底是什么,於是翻到了這一段處理事務異常的代碼:

TransactionAspectSupport.java
protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) {
	if (txInfo.transactionAttribute.rollbackOn(ex)) {
	}else{
		// We don't roll back on this exception.
		// Will still roll back if TransactionStatus.isRollbackOnly() is true.
		// 在checkedException的時候,不會被rollBack,會commit!!!
	}
}
@Override
public boolean rollbackOn(Throwable ex) {
	return (ex instanceof RuntimeException || ex instanceof Error);
}

看代碼邏輯就明白了,只有異常繼承RuntimeException或者Error的時候才會回滾!
好了,讓業務開發改了下代碼,問題解決了。

總結

遇到問題時,找到出問題代碼段和類似的正確代碼段的不同處,以此為切入,往往能抓住線索。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM