8.Spring的事務管理難點剖析

1.DAO和事務管理的牽絆:
  1.1 脫離了事務性,DAO照樣可以順利的進行;對於強調讀速度的應用,數據庫本事可能就不支持事務:如MyISAM引擎的MySQL數據可。這時,即使在應用中配置事務管理器,也沒實際用。
  1.2 Hibernate訪問數據庫:
        Hibernate的事務管理擁有其自身的意義,它和Hibernate一級緩存存在密切的關係:當我們調用Session的save、update等方法時,Hibernate並不直接向數據庫發送SQL語句,只在提交事務(commit)或flush一級緩存時才向數據庫發送SQL。所以,即使底層數據庫不支持事務,Hibernate的事務管理也不會對數據操作的效率造成負面影響。所以,如果使用Hibernate數據訪問技術,沒理由不配置HibernateTransactionManager事務管理器。(當然,不使用Hibernate 事務管理器,在Spring中,Hibernate也可以工作)。
  1.3 應用分層的迷惑:Web,Service、Dao三層劃分不是必須的。Spring框架所提供的各種好處(如AOP、註解增強、註解MVC等)的唯一前提就是讓POJO的類變成一個受Spring容器管理的Bean,除此之外沒有任何要求。比如:用一個POJO完成所有的功能,既是Controller,又是Service,還是Dao。(書P331)
  1.4 多線程的困惑:正常配置下,在相同線程中進行相互嵌套調用的事務方法工作於相同的事務中。如果這些相互嵌套調用的方法工作在不同的線程中,則不同線程下的事務方法工作在獨立的事務中。
  1.5 聯合軍種作戰的混亂
        很多應用中,往往採用多個數據訪問技術:一般是兩種,一種採用ORM技術框架,另一種採用偏JDBC的底層技術。如果你採用了一個高端ORM技術(Hibernate、JPA、JDO),同時採用一個JDBC技術(Spring JDBC、iBatis),由於前者的會話(Session)是對後者連接(Connection)的封裝,Spring會“足夠智能地”在同一個事務線程讓前者的會話封裝後者的連接。所以,我們只要直接採用前者的事務管理器就可以了。
                 混合數據訪問技術框架所對應的事務管理器:
混合數據訪問技術框架
事務管理器
Hibernate+ Spring JDBC或iBatis
org.springframework.orm.hibernate3.HibernateTransactionManager
JPA+Spring JDBC或iBatis
org.springframework.orm.jpa.JpaTransactionManager
JDO+Spring JDBC或iBatis
org.springframework.orm.jdo.JdoTransactionManager
eg. Hibernate+Spring JDBC混合框架的事務管理 實例(書P341)
      注:合適的時候需要顯示調用Hibernat裏的flush()方法,將Session中的緩存同步到數據庫中。原因:在默認情況下,Hibernate對數據的更改只是記錄在一級緩存中,要等事務提交或顯示調用flush()方法時纔將一級緩存中的數據同步到數據庫中。

1.6 特殊方法成漏網之魚
動態代理策略
不能被事務增強 的方法
基於接口的動態代理
除public外的其他所以方法,此外public static也不能被增強
基於CGLib的動態代理
privat、static、final的方法
注意,這些方法不能被Spring進行AOP事務增強,是指這些方法不能啓動事務,但是外層的事務上下文依舊可以順利地傳播到這些方法中。 這些不能被Spring事務增強的方法和可被Spring事務增強的方法唯一的區別在於“是否可以主動啓動一個新事務”:前者不能後者可以。對於事務傳播行爲來說,二者是完全相同的。

1.7數據連接泄漏
    如果代碼中直接獲取Connection,如不及時關閉,可能會造成連接泄漏。實例:書P351
    如何獲取這些被Spring管控的數據連接呢? Spring提供了兩種解決方法:其一是使用數據資源獲取工具類;其二是對數據源(或其衍生品如Hibernate SessionFactory)進行代理。
    通過DataSourceUtils獲取數據連接,如果不掉用release方法釋放連接,只能防止事務方法裏的數據連接泄漏,如果還想在一般方法裏防止這個問題,必須顯示調用release方法(注:放在finally後面)。見書P356.
   代碼獲取數據源,對數據源(或其衍生品如Hibernate SessionFactory)進行代理只是能處理存在事務上下文的方法裏的連接泄漏問題。
   不同數據訪問框架DataSourceUtils與TransactionAwareDataSourceProxy的等價類(書P359)
   總結,如果要直接獲取Connection,不及時關閉,就很可能造成連接泄漏。爲降低連接泄漏的可能性,儘量使用DataSourceUtils獲取數據連接,別忘了調用在finally裏顯示調用這個DataSourceUtils的releaseConnection釋放連接
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章