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() 方法时报异常。