在目前使用的現(xiàn)有框架當(dāng)中,利用spring的AOP機(jī)制來控制事務(wù)處理是目前最流行的一種控制事務(wù)的方式。
但是我們在某種使用場合的過程中,為什么有時事務(wù)處理老是不起作用呢?這里,為您道出原因之一,
首先請看一段話
Spring的事務(wù)實(shí)現(xiàn)采用基于AOP的攔截器來實(shí)現(xiàn),如果沒有在事務(wù)配置的時候注明回滾的checked exception,那么只有在發(fā)生了unchecked exception的時候,才會進(jìn)行事務(wù)回滾。
有必要先解釋一下checked exception與unchecked exception:
先看看EXCEPTION在JDK文檔當(dāng)中的結(jié)構(gòu)
java.lang.Object
java.lang.Throwable
java.lang.Exception
java.lang.RuntimeException
而Unchecked exception: 這類異常都是RuntimeException的子類,雖然RuntimeException同樣也是Exception的子類,但是它們是特殊的。Exception是作為checked Exception 出現(xiàn)的。
所以,除了Error與RuntimeException,其他剩下的異常都是你需要關(guān)心的,而這些異常類統(tǒng)稱為Checked Exception
有了以上的基礎(chǔ),看看我們框架當(dāng)中的事務(wù)屬性
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly </prop>
<prop key="save*">PROPAGATION_REQUIRED </prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED </prop>
</props>
</property>
此處,我們沒有指定任何異常,那么它目前默認(rèn)處理的就是unchecked exception了,再結(jié)合我們自身每個項(xiàng)目的模塊,在我們的每個項(xiàng)目當(dāng)中幾乎都定義了自己的異常,這些異常都是繼承自Exception,很不幸的是,我們繼承的Exception包括自己定義的異常,都是checked exception。
所以,在我們的事務(wù)處理機(jī)制當(dāng)中,事務(wù)不管用了。
解決辦法有2個:
1,在事務(wù)屬性后面加上需要回滾的checked exception。比如<prop key="save*">PROPAGATION_REQUIRED,-XXXXException</prop>(注意那個"-",對應(yīng)的是"+")
2, 不改配置文件,將需要事務(wù)回滾的異常繼承自unchecked exception類,也就是RuntimeException。
(nighthawk)