Spring 事务 (二) Spring 声明式事务 配置
2. Spring 声明式事务 配置
由Spring 事务 (一)知道,Spring事务基本概念中,最重要的是
PlatformTransactionManager,它的
TransactionStatus getTransaction(TransactionDefinition definition)
方法根据一个TransactionDefinition生成TransactionStatus.
这样可知,配置事务,首先需要配置一个PlatformTransactionManager信息,
然后需要配置 TransactionDefinition信息.而TransactionStatus是返回的值,
根据前面两个配置由TransactionStatus对象获取相应的配置信息.
所以配置时,主要配置PlatformTransactionManager,TransactionDefinition.
Spring的事务功能由事务代理完成.
一般的流程是:
先编写业务接口,
然后编写一个业务接口的实现类,并配置为bean(targetBean),
再配置一个TransactionProxyFactoryBean,得到一个代理bean(代理targetBean),
然后客户端代码中,通过代理bean的id来调用getBean方法,得到TransactionProxyFactoryBean配置的bean.
配置这个代理bean需要传入一个事务管理器(PlatformTransactionManager),一个目标bean(targetBean),
并指定事务代理的事务属性.
上述配置TransactionProxyFactoryBean的方式为显示的,即配置一个targetBean,和一个有事务行为的代理bean,
实际上配置了两个bean,而原来的targetBean是不直接使用的,假如代码中不小心使用了targetBean,则会产生问题.
因此Spring还提供了一种基于tx命名空间的方式来配置事务代理bean,这种配置类似于AOP配置,只配置一个bean,
当根据bean id使用getBean()获取bean实例时,Spring容器自动提供事务代理bean的实例.
http://www.ibm.com/developerworks/cn/education/opensource/os-cn-spring-trans/section5.html
上面链接中,还讨论了使用拦截器实现的事务(非事务代理bean方式),供参考.
2.1 PlatformTransactionManager配置
PlatformTransactionManager配置,根据不同数据源的使用,以及是局部事务还是全局事务 来分类,
主要有下面几种配置方式:
2.1.1 数据源使用JDBC数据源的局部事务,使用DataSourceTransactionManager类
<!-- 数据源使用JDBC数据源的局部事务,使用DataSourceTransactionManager类 --> <!-- DataSource配置,可配置为c3p0连接池等,这里省略 --> <bean id="dataSource" ...>...</bean> <bean id="transactionManager" class="org.springframework.jdbc.datasouce.DataSouceTransactionManager"> <!-- 配置DataSourceTransactionManager时,需要依赖注入DataSource的引用 --> <property name="dataSource" ref="dataSource"/> </bean>
2.1.2 采用全局事务的特定实现
<!-- 采用全局事务的特定实现 --> <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager" />
上面配置,无需指定datasource. 全局事务有JTA实现(比如有的容器weblogic等实现JTA,
也有专门的开源框架实现JTA,如JOTM)
2.1.3 使用Hibernate的配置
<!-- 使用Hibernate的配置 --> <!-- DataSource配置,可配置为c3p0连接池等,这里省略 --> <bean id="dataSource" ...>...</bean> <!-- Hibernate的SessionFactory配置,这里省略 --> <bean id="sessionFactory" ...>...</bean> <bean id="transactionManager" <!-- 针对Hibernate的特定实现类 --> class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <!-- 配置Hibernate时,需要依赖注入SessionFactory的引用 --> <property name="sessionFactory" ref="sessionFactory"/> </bean>
3 配置 TransactionProxyFactoryBean
3.1 配置一个targetBean(业务逻辑bean),和一个有事务行为的代理bean
<!-- 数据源使用JDBC数据源的局部事务,使用DataSourceTransactionManager类 --> <!-- DataSource配置,可配置为c3p0连接池等,这里省略 --> <bean id="dataSource" ...>...</bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 配置DataSourceTransactionManager时,需要依赖注入DataSource的引用 --> <property name="dataSource" ref="dataSource"/> </bean> <!-- 一个业务逻辑bean --> <bean id="newsDao" class="xxx.xxx.NewsDao" > <property name="ds" ref="dataSource" /> </bean> <!-- 为业务逻辑bean配置事务代理 --> <bean id="newsDaoTran" class="org.springframework.transaction.intereptor.TransactionProxyFactoryBean"> <!-- 注入事务管理器 --> <property name="transactionManager" ref="transactionManager" /> <!-- 指定被代理的目标bean --> <property name="target" ref="newDao" /> <!-- 指定事务属性 --> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED</prop> </props> </property> </bean>
上面transactionAttributes标示注入的是一个properties类型的属性.
key表示方面名称,可以使用通配符,
value表示事务规则:
指定事务属性的取值有较复杂的规则,具体的书写规则如下:
传播行为 [,隔离级别] [,只读属性] [,超时属性] [不影响提交的异常] [,导致回滚的异常]
只有传播行为是必须指定的,其他的可以省略(取默认值)
传播行为是唯一必须设置的属性,其他都可以忽略,Spring为我们提供了合理的默认值。
传播行为的取值必须以“PROPAGATION_”开头,
具体包括:
PROPAGATION_MANDATORY、
PROPAGATION_NESTED、
PROPAGATION_NEVER、
PROPAGATION_NOT_SUPPORTED、
PROPAGATION_REQUIRED、
PROPAGATION_REQUIRES_NEW、
PROPAGATION_SUPPORTS,共七种取值。
隔离级别的取值必须以“ISOLATION_”开头,
具体包括:
ISOLATION_DEFAULT、
ISOLATION_READ_COMMITTED、
ISOLATION_READ_UNCOMMITTED、
ISOLATION_REPEATABLE_READ、
ISOLATION_SERIALIZABLE,共五种取值。
如果事务是只读的,那么我们可以指定只读属性,
使用“readOnly”指定。否则我们不需要设置该属性。
超时属性的取值必须以“TIMEOUT_”开头,
后面跟一个int类型的值,表示超时时间,单位是秒。
不影响提交的异常是指,即使事务中抛出了这些类型的异常,
事务任然正常提交。必须在每一个异常的名字前面加上“+”。
异常的名字可以是类名的一部分。比如“+RuntimeException”、“+tion”等等。
导致回滚的异常是指,当事务中抛出这些类型的异常时,事务将回滚。
必须在每一个异常的名字前面加上“-”。异常的名字可以是类名的全部或者部分,
比如“-RuntimeException”、“-tion”等等。
以下是两个示例:
<property name="*Service"> PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED,TIMEOUT_20, +AbcException,+DefException,-HijException </property>
以上表达式表示,针对所有方法名以 Service 结尾的方法,
使用 PROPAGATION_REQUIRED 事务传播行为,
事务的隔离级别是 ISOLATION_READ_COMMITTED,
超时时间为20秒,
当事务抛出 AbcException 或者 DefException 类型的异常,则仍然提交,
当抛出 HijException 类型的异常时必须回滚事务。
这里没有指定"readOnly",表示事务不是只读的。
<property name="test">PROPAGATION_REQUIRED,readOnly</property>
以上表达式表示,针对所有方法名为 test 的方法,
使用 PROPAGATION_REQUIRED 事务传播行为,
并且该事务是只读的。
除此之外,其他的属性均使用默认值。
比如,隔离级别和超时时间使用底层事务性资源的默认值,
并且当发生未检查异常,则回滚事务,
发生已检查异常则仍提交事务。
参考:
http://www.ibm.com/developerworks/cn/education/opensource/os-cn-spring-trans/section5.html
3.2 基于tx命名空间的方式来配置事务代理bean
这种配置类似于AOP配置,只配置一个bean,
当根据bean id使用getBean()获取bean实例时,Spring容器自动提供事务代理bean的实例.
<?xml version="1.0" encoding="UTF-8"?> <!-- 需要使用这样的beans头,指定tx,aop的schema --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" > <!-- 数据源使用JDBC数据源的局部事务,使用DataSourceTransactionManager类 --> <!-- DataSource配置,可配置为c3p0连接池等,这里省略 --> <bean id="dataSource" ...>...</bean> <bean id="transactionManager" class="org.springframework.jdbc.datasouce.DataSouceTransactionManager"> <!-- 配置DataSourceTransactionManager时,需要依赖注入DataSource的引用 --> <property name="dataSource" ref="dataSource"/> </bean> <!-- 一个业务逻辑bean --> <bean id="newsDao" class="xxx.xxx.NewsDao" > <property name="ds" ref="newsDao" /> </bean> <!-- 配置增强处理的bean(相当于切面类),也是Spring自动生成普通 业务逻辑bean(targetBean)的代理Bean.里面的tx:method配置每个方法的事务属性, name配置方法名,可使用通配符. --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 配置详细的事务语义 --> <tx:attributes> <!-- 表示get开头的方法是只读的 --> <tx:method name="get*" read-only="true" /> <!-- 其他方法使用默认的事务设置,事务传播方式也可以默认么? --> <tx:method name="*" /> </tx:attributes> </tx:advice> <!-- AOP元素配置 --> <aop:config> <!-- 配置一个切入点 xxx.xxx包下面所有已Imp1结尾的类的所有方法--> <aop:pointcut id="myPoint" expression="execution(* xxx.xxx.*Imp1.*(..))" /> <!-- 配置 (事务代理)切入点(aop:pointcut) 和 切面类(tx:advice),将二者关联起来 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="myPoint" /> </aop:config> </beans>
注:
aop:config中 aop:pointcut配置切入点,表名哪些方法将会被事务代理增强.
tx:advice 相当于配置一个切面类,并标明对符合条件的方法采用何种事务.
aop:config中aop:advisor将上述二者关联起来
<tx:attributes>的tx:method的
name属性是必须的,可以使用通配符,表示与改事务语义管理的方法名.
另外,还有属性:
propagation,isolation,timeout,read-only,rollbak-for,no-rallback-for.(P684)
附件中 classes12.jar是oracle的驱动包.
相关推荐
### 标题解读:Spring声明式事务配置 Spring框架提供了两种主要类型的事务管理方式:编程式事务管理和声明式事务管理。声明式事务管理通过XML配置或注解的形式定义事务边界,使得业务逻辑与事务控制分离。 ### ...
Spring声明式事务配置管理方法
在Spring框架中,声明式事务管理是实现事务处理...在博文"Spring使用XML配置声明式事务"中,作者详细讲解了每个步骤,并可能通过示例代码展示了如何实际应用这些配置,帮助读者更好地理解和掌握Spring声明式事务管理。
在"spring声明式事务管理配置方式"中,主要涉及到以下几个关键知识点: 1. **Spring事务管理器(Transaction Manager)**: - Spring支持多种事务管理器,如DataSourceTransactionManager(用于JDBC事务)和...
总的来说,Spring 3和Hibernate 4结合使用声明式事务管理,使得我们无需在代码中显式调用事务开始、提交和回滚,而是通过注解和配置文件来声明事务的边界和行为。这种方式降低了代码的复杂度,提高了可维护性和可...
在Spring中,声明式事务主要通过AOP(面向切面编程)实现,它允许我们在不修改业务代码的情况下,通过XML配置或Java配置,以及注解来控制事务的边界。 3. **XML配置事务** 在Spring的XML配置文件中,可以通过`...
以下是对Spring声明式事务配置的详细说明: 1. **Spring 1.x 声明事务方式** 在Spring 1.x中,声明式事务有两种主要的配置方式,第一种是通过XML配置逐个为每个业务类创建事务代理。首先,你需要声明一个事务管理...
Spring 提供了多种方式来实现声明式事务管理,例如使用 @Transactional 注解或使用 XML 配置文件。 总结 本文通过详细分析 Spring 的编程式事务管理及声明式事务管理,帮助读者理解事务管理的重要性和实现方式。...
1. **配置Spring声明式事务**: 在Spring中,声明式事务管理依赖于AOP(面向切面编程)来实现。首先,需要配置一个事务管理器,通常使用`DataSourceTransactionManager`,它与数据源`dataSource`关联。然后,通过`...
在 Spring 中,声明式事务处理可以通过配置 TransactionProxyFactoryBean 来实现。TransactionProxyFactoryBean 是一个 FactoryBean,它可以创建一个代理对象,该代理对象可以拦截业务方法的调用,并对事务进行管理...
在这个"spring声明式事务处理demo"中,我们将探讨如何在MyEclipse环境下实现这一功能。 首先,我们要理解Spring事务管理的两种主要方式:编程式事务管理和声明式事务管理。编程式事务管理通常通过AOP(面向切面编程...
在Spring框架中,声明式事务管理是通过AOP(面向切面编程)实现的,它允许开发者无需在业务代码中显式处理事务,而是通过配置来控制事务的边界。Spring提供了四种不同的方式来配置声明式事务,这使得事务管理更加...
文件名为`Spring声明式事务处理-1.mht`到`Spring声明式事务处理-5.mht`,通过阅读这些文件,你将能够深入理解Spring声明式事务处理的各个方面,包括配置、使用场景、最佳实践以及常见问题的解决方法。
Spring_Hibernate使用TransactionInterceptor声明式事务配置 在这篇文章中,我们将探讨使用Spring_Hibernate框架实现声明式事务配置的方法,具体来说,就是使用TransactionInterceptor来管理事务。在Spring框架中,...
其中,声明式事务因其简单易用而被广泛采用。本文将详细介绍Spring中事务配置的五种方式,帮助开发者更好地理解和运用这些配置方法。 #### 二、Spring事务配置的基本组成部分 Spring事务配置主要包含以下三个核心...
本主题将深入探讨Hibernate的编程式事务管理和Spring AOP的声明式事务管理,以及两者如何在实际项目中集成使用。 **Hibernate编程式事务管理** Hibernate作为流行的ORM(对象关系映射)框架,提供了对JDBC事务的...
在Spring框架中,声明式事务管理是一种非常重要的特性,它允许开发者通过XML配置或注解来定义事务的边界,而无需在业务代码中显式地管理事务。这种方式极大地提高了代码的可读性和可维护性。本篇文章将深入探讨如何...