补充说明:
使用事务的目的是将整个业务的逻辑处理置于同一个事务中,方便对整个业务进行管理,如业务的事务回滚;
一、什么是声明式事务管理:
在编写代码时,为了将一个业务的核心逻辑处理放入事务中,有时会这样写:
Session session = sf.openSession();//打开一个session
session.getTransaction().begin();//开启一个事务
Query query = session.createQuery("from News");//核心逻辑处理
List<News> allNewList = query.getResultList();//核心逻辑处理
session.getTransaction().commit();//提交事务
session.close();//关闭session
如果一个项目中有很多个业务都要用到事务,那么每次都需要将打开session、开启事务、提交事务、关闭session等步骤执行一遍,如果每次都直接编写相应的代码来执行,肯定不合适,因为这几个步骤都是固定不变,所以我们可以利用spring的aop,将这几个步骤放到横切关注点中,交由spring来帮我们执行,而我们只需要声明一下,告诉spring,哪些业务需要使用事务
二、实现声明式事务管理
1.配置applicationContext.xml文件,加入下列代码
<!-- 配置事务-->
<!-- 配置Hibernate的局部事务管理器,使用HibernateTransactionManager类-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<!-- HibernateTransactionManager bean需要依赖注入一个SessionFactory bean的引用 -->
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- 配置事务增强处理,指定事务管理器 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="get*" propagation="REQUIRED" read-only="true"/>
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<!-- 配置一个切入点,匹配news.service下所有类执行的所有方法 -->
<aop:pointcut id="txPointCut" expression="execution(* news.service.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
2.修改之前的事务处理 ;
Session session = sf.openSession();//打开一个session
session.getTransaction().begin();//开启一个事务
Query query = session.createQuery("from News");//核心逻辑处理
List<News> allNewList = query.getResultList();//核心逻辑处理
session.getTransaction().commit();//提交事务
session.close();//关闭session
改为:
Session session = sf.getCurrentSession();//获取session
Query query = session.createQuery("from News");//核心逻辑处理
List<News> allNewList = query.getResultList();//核心逻辑处理
openSession()是新建一个session,在使用声明式事务管理后,事务都交由spring去处理,不必再写开启事务、提交事务的代码,同时所有的transaction都使用同一个session,这个session是spring来管理的的,所以无需再自己open一个新的session,直接向spring get即可,而且get了spring的session后,无需编写close(),spring会自动帮我们关闭,而如果不小心用的是自己open的新的session,最后还要自己写close(),spring不会自动帮我们关闭