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釋放連接