有時候配置了註解@Transactional,可是它會失效,這裏要注意一些細節問題,以免落入陷阱。
註解@Transaction的底層實現是Spring AOP技術,而Spring AOP技術使用的是動態代理。這就意味着對於靜態(static)方法和非public方法,註解@Transactional是失效的。還有一個更爲隱祕的,並且在使用過程當中極其容易犯錯誤的——自調用。
所謂自調用,就是一個類的一個方法去調用自身另一個方法的過程。數據庫
出現這個的問題根本緣由在於AOP的實現原理。因爲@Transactional的實現原理是AOP,而AOP的實現原理是動態代理,而本身調用本身的過程,並不存在代理對象的調用,這樣就不會產生AOP去爲咱們設置@Transactional配置的參數,這樣就出現了自調用註解失效的問題。
爲了克服這個問題,一方面可使用兩個服務類,Spring IoC容器中爲你生成了RoleService的代理對象,這樣就可使用AOP,且不會出現自調用的問題。另一方面,你也能夠直接從容器中獲取Service的代理對象,從IoC容器中獲取RoleService代理對象。可是有一個弊端,就是從容器獲取代理對象的方法有侵入之嫌,你的類須要依賴於Spring IoC容器性能
數據事務是企業應用關注的核心內容,也是開發者最容易犯錯的問題,所以筆者在這裏講解一些使用不良習慣,注意它們能夠避免一些錯誤和性能的丟失。代理
互聯網每每採用模型—視圖—控制器(Model View Con-troller,MVC)來搭建開發環境,所以在Controller中使用Service是十分常見的。
在Controller每調用一次帶事務的service都會建立數據庫事務。若是屢次調用,則不在同一個事務中,這會形成不一樣時提交和回滾不一致的問題。每個Java EE開發者都要注意這類問題,以免一些沒必要要的錯誤。對象
在企業的生產系統中,數據庫事務資源是最寶貴的資源之一,使用了數據庫事務以後,要及時釋放數據庫事務。換言之,咱們應該儘量地使用數據庫事務資源去完成所需工做,可是在一些工做中須要使用到文件、對外鏈接等操做,而這些操做每每會佔用較長時間,針對這些,若是開發者不注意細節,就很容易出現系統宕機的問題。
一些系統之間的通訊及一些可能須要花費較長時間的操做,都要注意這個問題,放在controller層等事務外進行處理,以免長時間佔用數據庫事務,致使系統性能的低下。事務
帶事務的service中,出現異常想要回滾時應拋出異常,而不是捕獲資源