声明式事务的缺点在于:只能作用到方法级别,无法做到像编程式事务那样能控制到代码块级别。
spring3声明式事务在底层采用了AOP技术,既可以通过AOP配置方式实现,也可以通过@Transaction注解方式实现。
事务传播行为:
REQUIRED:表示当前方法必须运行在一个事务环境中,如果一个现有事务正在运行,该方法将运行在这个事务中,否则,就要开始一个新事务。
REQUIRESNEW:表示当前方法必须运行在自己的事务里。
SUPPORTS:表示当前方法不需要事务处理环境,但如果有一个事务正在运行,则这个方法也可以运行在其中。
MANDATORY:表示当前方法必须运行在一个事务上下文中,否则就会抛出异常。
NEVER:表示当前方法不应该运行在一个事务上下文中,否则就会抛出异常。
事务管理的主要任务是事务的创建、事物的回滚和事务的提交,是否需要创建事务及如何创建事务,是由事务传播行为控制的。
不指定传播行为的话,spring3默认采用REQUIRED。
对基于方法级别的事务管理来说,方法开始执行时创建事务,方法执行过程如果出现异常,进行事务回滚,方法如果正常执行完成,提交事务。
①在代码中去除硬编码的事务操作,运行项目后出错: createCriteria is not valid without active transaction,即createdCriteria无效,没有活动的事务。错误原因在于spring配置文件<property name="hibernateProperties">中配置了hibernate.current_session_context_class属性,将线程配置成了Thread级别。
②将以上删除,这样才能将Hibernate的session交给spring来管理。重启Tomcat,在此出错信息:Could not obtain transaction-synchronized Session for current thread,即无法获取session,这是因为getCurrentSession()在没有Session情况下不会自动创建,Hibernate4必须配置为开启事务,否则getCurrentSession()获取不到session。
③配置声明式事务:<beans>中添加AOP所需的常用命令空间声明(xmlns:aop="http://www.springframework.org/schema/aop···")
声明事务管理器:spring配置文件中自动生成<bean id="transactionManager" ·····>
定义事务通知:需要指定一个事务管理器,然后在其属性中声明事务规则:
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 指定事务传播规则 -->
<tx:attributes>
<!-- 对所有方法应用REQUIRED事务规则 -->
<tx:method name="*" propatation="REQUIRED"></tx:method>
</tx:attributes>
</tx:advice>
这样就解决了先前的getCurrentSession()获取不到Session的问题。
定义一个切面,并将事务通知与切面组合,即定义哪些方法应用这些规则:
<aop:config>
<aop:pointcut id="bizMethods" expression="execution(* com.ssh2.biz..*.*(..))" />//这里测试的时候*和com之间没有空格会报错
<aop:advisor advice-ref="txAdvice" pointcut-ref=:bizMethods: />
</aop:config>
至此,基于AOP的声明式事务配置完成。
基于AOP事务管理实现银行转账:
讲述如何在包含多个操作的业务方法中使用事务管理,从而保证数据库的安全性和一致性。
1、生成实体类和映射文件,bookshop中的account表,逆向工程成实体类、映射文件。
2、实现DAO层
3、实现Biz层
4、创建Action:AccountManager.java
5、applicationContext.xml配置中配置dao、biz、action的bean,struts.xml中配置action、result
这里注意:因为新建了Action.java实体类,所以applicationContext.xml中sessionFactory也要增加mappingResources的实体类映射。
之前没手动添加,一直无法查询到数据库信息,criterria查询的list一直为空,开始怀疑查询条件不对,后来觉得可能连接不上数据库,最后才发现没有配置映射信息^_^.
6、编写jsp页面,测试