事務失效爲哪般?

       最近生產環境發現一個很奇怪的問題,以前用的好好的Spring事務配置在一個接口上忽然失效了,其他接口正常。緣由到底是什麼呢?且聽我慢慢道來。:-)git

問題描述:spring

注:問題的描述是在demo工程中對原問題的模擬,只是爲了說明問題,因此數據看起來有點隨意,請勿見怪。數據庫

數據庫表userinfo中有兩條數據post

clip_image002

配置Sping事務並對兩條記錄進行同時刪除,此時因爲兩條delete中間有一個異常拋出,因此兩條記錄不會被刪除,一切到這仍是很是合乎常理的。測試

clip_image004

clip_image006

走讀問題代碼發現工程中有一個類實現了BeanFactoryPostProcessor接口,而且在postProcessBeanFactory方法中對上面調用的接口調用了getBeansOfType,因而在demo中進行模擬,相似於下面這樣:.net

此時,咱們在demo工程配置MyBeanFactoryPostProcessor對應的bean,從新調用接口中的delete方法,從結果能夠看出,方法中的兩個delete操做已經不在同一事務中了,也就是說Spring事務失效了!代理

clip_image010

問題分析:日誌

MyBeanFactoryPostProcessor的bean存在前,能夠看到對應的事務配置生效,並生成了代理類。接口

clip_image012

而配置MyBeanFactoryPostProcessor以後,沒有事務的代理類生成了,固然事務也就會失效。事務

那麼爲何新加一個實現了BeanFactoryPostProcessor接口的類就會有這個影響呢?

clip_image014

如上圖所示,spring的bean初始化過程當中,會在圖中的1)處調用實現了BeanFactoryPostProcessor的類中的postProcessBeanFactory方法對beanFactory進行後處理

而後執行到圖中的2)處調用BeanPostProcessor的方法攔截bean的建立過程,作一些前置後置處理,spring的aop生成代理類(如本文中的事務切面)就是在這裏完成的

MyBeanFactoryPostProcessor實現了BeanFactoryPostProcessor接口,並在postProcessBeanFactory中調用getBeansOfType完成了對userDao的實例化,執行到2)時

也就不能生成對應的代理類,從而致使了事務配置的實效。上面的分析也能夠從spring的啓動日誌中獲得驗證:

clip_image016

當MyBeanFactoryPostProcessor存在時,在internalAutoProxyCreator以前,userDao的bean已經完成了實例化。

clip_image018

而沒有MyBeanFactoryPostProcessor的狀況下,userDao是能夠生成事務代理類的。

注:AspectJAwareAdvisorAutoProxyCreator實現了BeanPostProcessor接口

最後咱們也能夠從類的註釋說明看出spring是不建議經過實現BeanFactoryPostProcessor來與bean的實例化進行交互的。

測試工程:https://git.oschina.net/zjg23/SpringTransactionTest

相關文章
相關標籤/搜索