1. 程式人生 > >學習SSH框架記錄片4----Spring 宣告式事務整合 Hibernate

學習SSH框架記錄片4----Spring 宣告式事務整合 Hibernate

1.配置事務管理器

1-1. XML配置示例

<bean id="transactionManager"       class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"></property>
</bean>

1-2. 說明
1> 類 HibernateTransactionManager 在 spring-orm-4.3.5.RELEASE.jar 包中,選中對應的 Hibernate 版本即可
2> 屬性中配置該事務管理器所用到的 Bean,即類 LocalSessionFactoryBean

2.配置事務屬性,需要事務管理器

2-1. XML配置示例

<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="get*" read-only="true" />
        <tx:method name="purchase" propagation="REQUIRES_NEW"/>
        <tx:method name="*" />
    </tx:attributes
>
</tx:advice>

2-2. 說明
1> 使用 <tx> 節點需要引入 tx 的 XML 名稱空間
2> 屬性 transaction-manager 指定了 事務管理器
3> 節點 <tx:attributes> 是事務屬性集合
4> 節點 <tx:method> 指定具體的事務屬性,可配置傳播行為、隔離級別、超時、異常回滾等屬性
5> 屬性 name 指定方法名稱,可使用萬用字元
6> propatation 指定事務傳播行為,預設值為 REQUIRED,表示使用當前事務,而 REQUIRES_NEW 表示使用新事務

3.配置事務切點,並把切點和事務屬性關聯起來

3-1. XML配置示例

<aop:config>
    <aop:pointcut expression="execution(* com.test.spring.hibernate.service.*.*(..))"
    id="txPointcut" />
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" /> 
</aop:config>

3-2. 說明

1> 使用 <aop> 節點需要引入 aop 的 XML 名稱空間
2> 節點 <aop:pointcut> 用於配置切點
3> 屬性 expression 用於指定連線點,其中萬用字元 【*】 可表示【許可權訪問修飾符、返回值型別、類名、方法名】,而 .【..】表示任意引數
4> 節點 <aop:advisor> 用於關聯切點和事務
5> 屬性 advice-ref 指定引用的事務,pointcut-ref 指定引用的切點

4.綜合理解

4-1. 配置事務屬性
如上所述,就是為了滿足一些業務需求,配置不同的屬性資訊。

4-2. 配置事務切點
例如,上面的方法 purchase 是一個連線點,這樣的話,在執行切點方法時,Spring 的事務管理器會自動呼叫事務相關的方法,開啟事務,提交事務等,因為這個切面是 Spring 提供的,所以我們只需要關聯一下即可,若是日誌、異常之類的切面,則需要自己開發相關類,並在其中指定切點。

5.注意事項

5-1. 如果註釋掉 <aop> 相關的配置,則報異常

org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
at org.springframework.orm.hibernate5.SpringSessionContext.currentSession(SpringSessionContext.java:133)
t org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:456)

5-2. 原因

在事務開始之前,獲取 Session,然後和執行緒繫結,再由 SessionFactory.getCurrentSession() 得到與執行緒繫結的 Session,因為註釋掉了事務和切點的關聯,執行切點對應的方法時,也就不會啟用事務,從而也不會執行 Session 和當前執行緒繫結的操作,導致呼叫 getCurrentSession() 方法時報異常。