<bean id="petStore" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref bean="transactionManager"/></property> <property name="target"><ref bean="petStoreTarget"/></property> <property name="transactionAttributes"> <props> <prop key="insert*">PROPAGATION_REQUIRED,-MyCheckedException</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> </props> </property> </bean>
事 务代理会实现目标对象的接口:这里是id为petStoreTarget的bean。(使用 CGLIB也可以实现具体类的代理。只要设置proxyTargetClass属性为true就可以。如果目标对象没有实现任何接口,这将自动设置该属性 为true。通常,我们希望面向接口而不是类编程。)使用proxyInterfaces属性来限定事务代理来代 理指定接口也是可以的(一般来说是个好想法)。也可以通过从 org.springframework.aop.framework.ProxyConfig继承或所有AOP代理工厂共享 的属性来定制TransactionProxyFactoryBean的行为。
这里的transactionAttributes属性定义在 org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource 中的属性格式来设置。这个包括通配符的方法名称映射是很直观的。注意 insert*的映射的值包括回滚规则。添加的-MyCheckedException 指定如果方法抛出MyCheckedException或它的子类,事务将 会自动回滚。可以用逗号分隔定义多个回滚规则。-前缀强制回滚,+前缀指定提交(这允许即使抛出unchecked异常时也可以提交事务,当然你自己要明白自己 在做什么)。
TransactionProxyFactoryBean允许你通过 “preInterceptors”和“postInterceptors”属性设置“前”或“后”通知来提供额外的 拦截行为。可以设置任意数量的“前”和“后”通知,它们的类型可以是 Advisor(可以包含一个切入点), MethodInterceptor或被当前Spring配置支持的通知类型 (例如ThrowAdvice, AfterReturningtAdvice或BeforeAdvice, 这些都是默认支持的)。这些通知必须支持实例共享模式。如果你需要高级AOP特 性来使用事务,如有状态的maxin,那最好使用通用的 org.springframework.aop.framework.ProxyFactoryBean, 而不是TransactionProxyFactoryBean实用代理创建者。
也可以设置自动代理:配置AOP框架,不需要单独的代理定义类就可以生成类的 代理。
附两个spring的事务配置例子:
<prop key="add">
PROPAGATION_REQUIRES_NEW, -MyException
</prop>
注:上面的意思是add方法将独占一个事务,当事务处理过程中产生MyException异常或者该异常的子类将回滚该事务。
<prop key="loadAll">
PROPAGATION_SUPPORTS, ISOLATION_READ_COMMITED, Readonly
</prop>
注:表示loadAll方法支持事务,而且不会读取没有提交事务的数据。它的数据为只读(这样有助于提高读取的性能)
附A Spring中的所有事务策略
PROPAGATION_MANDATORY
PROPAGATION_NESTED
PROPAGATION_NEVER
PROPAGATION_NOT_SUPPORTED
PROPAGATION_REQUIRED
PROPAGATION_REQUIRED_NEW
PROPAGATION_SUPPORTS
附B Spring中所有的隔离策略:
ISOLATION_DEFAULT
ISOLATION_READ_UNCOMMITED
ISOLATION_COMMITED
ISOLATION_REPEATABLE_READ
ISOLATION_SERIALIZABLE
大家可能在spring中经常看到这样的定义:
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop><prop key="store*">PROPAGATION_REQUIRED</prop>
估计有好多朋友还没有弄清楚里面的值的意思,仔细看完下面应该知道自己什么情况下面应该使用什么样的声明。^_^
Spring中常用事务类型:
- PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
- PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
- PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
- PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
- PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
- PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
Spring 和EJB一样,提供了两种事务管理方式:编程式和声明式。在考试系统中我们将使用声明式的事务管理,这是spring推荐的做法。使用这种方式可以体验到 spring的强大便捷,而且我们无须在Dao类中编写任何特殊的代码,只需要通过配置文件就可以让普通的java类加载到事务管理中,这个意义是很重大 的。
本文Matrix永久镜像:http://www.matrix.org.cn/resource/article/1/1339.html
说明:本文可能由Matrix原创,也可能由Matrix的会员整理,或者由
Matrix的Crawler在全球知名Java或者其他技术相关站点抓取并永久
保留镜像,Matrix会保留所有原来的出处URL,并在显著地方作出说明,
如果你发觉出处URL有误,请联系Matrix改正.
Spring 和EJB一样,提供了两种事务管理方式:编程式和声明式。在考试系统中我们将使用声明式的事务管理,这是spring推荐的做法。使用这种方式可以体验到 spring的强大便捷,而且我们无须在Dao类中编写任何特殊的代码,只需要通过配置文件就可以让普通的java类加载到事务管理中,这个意义是很重大 的。
Spring中进行事务管理的通常方式是利用AOP(面向切片编程)的方式,为普通java类封装事务控制,它是通过动态代理实现 的,由于接口是延迟实例化的,spring在这段时间内通过拦截器,加载事务切片。原理就是这样,具体细节请参考jdk中有关动态代理的文档。本文主要讲 解如何在spring中进行事务控制。
动态代理的一个重要特征是,它是针对接口的,所以我们的dao要通过动态代理来让spring接管事务,就必须在dao前面抽象出一个接口,当然如果没有这样的接口,那么spring会使用CGLIB来解决问题,但这不是spring推荐的方式,我们也不做讨论。
参照前面的例子,我们为StudentManager.java定义一个接口,它的内容如下:
/* * 创建日期 2005-3-25 */ package org.bromon.spring.examer.student; import java.util.List; import org.bromon.spring.examer.pojo.Student; /** * @author Bromon */ public interface StudentManagerInterface { public void add(Student s); public void del(Student s); public void update(Student s); public List loadAll(); public Student loadById(int id); }
StudentManager也应该做出修改,实现该接口:
public class StudentManager extends HibernateDaoSupport implements StudentManagerInterface
现 在需要修改配置文件,用于定义Hibrenate适用的事务管理器,并且把sessionFactory注入进去,同时还需要通过注册一个 DefaultTransactionAttribute对象,来指出事务策略。其中sessionFactory的定义已经在本文的第三章中说明。
首先定义一个Hibernate的事务管理器,让它来管理sessionFactory:
<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"> <property name="sessionFactory"> <ref bean="sessionFactory"/> </property> </bean>
下面定义事务管理策略,我们希望把策略定义在方法这个级别上,提供最大的灵活性,本例中将add方法定义为:PROPAGATION_REQUIRES_NEW,这可以保证它将始终运行在一个事务中。
<bean id="transactionAttributeSource" class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource"> <property name="properties"> <props> <prop key="add"> PROPAGATION_REQUIRES_NEW </prop> </props> </property> </bean>
我们不仅可以为add方法定义事务策略,还可以定义事务隔离程度和回滚策略,他们以逗号隔开,比如我们的add事务可以定义为:
<prop key="add"> PROPAGATION_REQUIRES_NEW,-ExamerException </prop>
这个事务策略表示add方法将会独占一个事务,当事务过程中产生ExamerException异常,事务会回滚。
Add/update/del都是写入方法,对于select(读取)方法,我们可以指定较为复杂的事务策略,比如对于loadAll()方法:
<prop key=”loadAll”> PROPAGATION_SUPPORTS,ISOLATION_READ_COMMITED,readOnly </prop>
该事务的含义为,loadAll方法支持事务,不会读去位提交的数据,它的数据为只读(可提高执行速度)。
如 你所见,我们的StudentManagerInterface接口中还有一个loadById(int id)方法,也许我们将来还会有很多的loadByXXXX的方法,难道要意义为他们指定事务策略?太烦人了,他们应该和loadAll()一样,所以我 们可以使用通配符,定义所有的loadXXXX方法:
<prop key=”load*”> PROPAGATION_SUPPORTS,ISOLATION_READ_COMMITED,readOnly </prop>
现在可以定义事务管理器:
<bean id="studentManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="target"> <ref bean="studentManager"/> </property> <property name="transactionManager"> <ref bean="transactionManager"/> </property> <property name="transactionAttributeSource"> <ref bean="transactionAttributeSource"/> </property> </bean>
这 个bean的外观是一个接口(StudentManagerInterface),我们指出了它的具体实现(studentManager),而且为它绑 定了事务策略。在客户端使用的时候,获得对象是StudentManagerInterface,所有的操作都是针对这个接口的。测试代码并没有改变,我 们虽然修改了很多地方,加入了事务控制,但是客户端并没有受到影响,这也体现了spring的一些优势。测试代码如下:
public void testAdd() { ApplicationContext ctx=new ClassPathXmlApplicationContext("springConfig.xml"); StudentManager sm=(StudentManager)ctx.getBean("studentManager"); Student s=new Student(); s.setId(1); s.setName("bromon"); s.setPassword("123"); s.setGrade(1); s.setSex(0); sm.add(s); }
通过以上的代码可以看出,spring可以简单的把普通的java class纳入事务管理,声明性的事务操作起来也很容易。有了spring之后,声明性事务不再是EJB独有,我们不必为了获得声明性事务的功能而去忍受EJB带来的种种不便。
我所使用的mysql是不支持事务的,你可以更换使用PostgreSQL,有了spring+hibernate,更换db并不像以前那样恐怖了,步骤很简单:
1、 添加PostgreSQL的jdbc驱动
2、 修改dataSource配置,包括驱动名称、url、帐号、密码
3、 修改sessionFactory的数据库dailet为net.sf.hibernate.dialect.PostgreSQLDialect
4、 修改hbm.xml中的主键生成策略为increment
所有的修改都在配置文件中完成,业务代码不需要任何修改,我很满意,How about u?
spring声明式事务管理的两种方式
2 <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
3 <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:dev" />
4 <property name="username" value="kaktos" />
5 <property name="password" value="kaktos" />
6 </bean>
7
8 <bean id="txManager"
9 class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
10 <property name="dataSource" ref="dataSource" />
11 </bean>
12
13 <bean id="businessBean"
14 class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
15 <property name="transactionManager" ref="txManager" />
16 <property name="target" ref="businessBeanTarget" />
17 <property name="transactionAttributes">
18 <props>
19 <prop key="*">PROPAGATION_REQUIRED</prop>
20 </props>
21 </property>
22 </bean>
23
24 <bean id="businessBeanTarget" class="sample.spring.trans.BusinessBean">
25 <property name="dataSource" ref="dataSource" />
26 </bean>
这样做的弊端就是不得不为每个需要事务的bean做一次声明,如果所有的bean都基本上有一致的配置,这样就太繁琐啦。
下面是第二种方式:
2 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
3 <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
4 <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:dev" />
5 <property name="username" value="kaktos" />
6 <property name="password" value="kaktos" />
7 </bean>
8
9 <bean id="txManager"
10 class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
11 <property name="dataSource" ref="dataSource" />
12 </bean>
13
14 <bean id="matchAllWithPropReq"
15 class="org.springframework.transaction.interceptor.MatchAlwaysTransactionAttributeSource">
16 <property name="transactionAttribute" value="PROPAGATION_REQUIRED" />
17 </bean>
18
19 <bean id="matchAllTxInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
20 <property name="transactionManager" ref="txManager" />
21 <property name="transactionAttributeSource" ref="matchAllWithPropReq" />
22 </bean>
23
24 <bean id="autoProxyCreator"
25 class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
26 <property name="interceptorNames">
27 <list>
28 <idref local="matchAllTxInterceptor" />
29 </list>
30 </property>
31 <property name="beanNames">
32 <list>
33 <idref local="businessBean" />
34 </list>
35 </property>
36 </bean>
37
38 <!-- my beans -->
39 <bean id="businessBean" class="sample.spring.trans.BusinessBean">
40 <property name="dataSource" ref="dataSource" />
41 </bean>
42 </beans>
BeanNameAutoProxyCreator会在applicationcontext初始化后自动为beanNames属性中的bean建立proxy。
相关推荐
Spring事务管理的目的是确保数据的一致性和完整性,尤其是在多操作、多资源的环境中。本Demo将深入探讨Spring如何实现事务的管理。 首先,Spring提供了两种主要的事务管理方式:编程式事务管理和声明式事务管理。 ...
本资源包提供了进行Spring事务管理开发所需的所有关键库,包括框架基础、核心组件、AOP(面向切面编程)支持、日志处理、编译工具以及与数据库交互的相关jar包。下面将对这些知识点进行详细解释: 1. **Spring框架*...
本篇将深入探讨Spring事务管理的核心概念、工作原理以及如何使用`spring-tx-3.2.0.RELEASE.jar`这个jar包。 首先,我们需要理解什么是事务。在数据库系统中,事务是一组操作,这些操作被视为一个整体,要么全部完成...
标题“Spring事务管理失效原因汇总”指出了本文的核心内容是分析在使用Spring框架进行事务管理时可能遇到的问题及其原因。描述部分进一步说明了事务失效的后果往往不明显,容易在测试环节被忽略,但在生产环境中出现...
Spring 框架是Java开发中...理解并熟练掌握Spring事务管理,对于提升应用程序的稳定性和可靠性至关重要。在实际开发中,结合声明式事务管理、事务传播行为、隔离级别和回滚规则,可以有效地确保数据的完整性和一致性。
Spring事务管理.pdf 1.资料 2.本地事务与分布式事务 3.编程式模型 4.宣告式模型
本篇文章将深入探讨Spring事务管理的五种方法,旨在帮助开发者更好地理解和运用这一核心特性。 首先,我们来了解什么是事务。在数据库操作中,事务是一组逻辑操作,这些操作要么全部成功,要么全部失败,确保数据的...
### Spring事务管理详解 #### 一、Spring事务管理概述 Spring框架提供了强大的事务管理功能,使得开发者能够更方便地管理应用程序中的事务。Spring事务管理主要包括两种类型:编程式事务管理和声明式事务管理。 -...
实验 "Spring 声明事务" 是 Java 高级编程中的一个重要环节,旨在让学生掌握 Spring 框架中声明式事务管理的配置和使用。在实际应用中,事务管理是确保数据一致性、完整性和可靠性的关键组件。Spring 提供了声明式...
在Spring框架中,事务管理是核心功能之一,它确保了数据操作的一致性和完整性。本教程将深入探讨如何在Spring中实现自定义事务管理器...这将加深你对Spring事务管理的理解,帮助你在实际项目中更加熟练地运用这些技术。
Spring事务管理是Spring框架的核心特性之一,主要用于处理应用程序中的数据一致性问题。在Spring中,事务管理分为编程式和声明式两种方式。本篇文章将详细解释Spring事务管理的流程,以及如何通过时序图来理解这一...
### Spring事务与数据库操作 #### 一、Spring的声明式事务管理 在现代软件开发中,事务处理是非常关键的一部分,特别是在涉及多个数据操作时。Spring框架提供了强大的事务管理能力,可以方便地集成到应用程序中。...
首先,Spring事务管理的核心概念是ACID(原子性、一致性、隔离性和持久性),这是所有事务系统的基础。在Spring中,事务管理分为两种模式:声明式事务管理和编程式事务管理。声明式事务管理通过配置元数据(如XML或...
在本文中,我们将深入探讨Spring框架中的事务管理。Spring是一个广泛应用的Java企业级应用开发框架,它提供...如果你想要深入了解,可以参考提供的博客链接或其他相关资料,进一步学习Spring事务管理的细节和最佳实践。
Spring 框架的事务管理是其核心特性之一,它为开发者提供了强大的支持,确保了在多线程和并发环境中数据的一致性和完整性。本教程将深入探讨 Spring 的编程式事务管理和声明式事务管理,帮助你理解这两种方式的差异...
Spring 3.0 提供了两种事务管理配置方法:基于 XML 的事务管理和基于 @Transactional 的事务管理,这两种方法都是为了实现事务管理的目标,分别具有不同的配置方式和优缺点。 基于 XML 的事务管理 这种方法不需要...
Spring事务管理就是围绕这些特性来确保数据的一致性。 四、事务的传播行为 在Spring中,我们可以配置事务的传播行为,比如REQUIRED(默认,如果当前存在事务,则加入当前事务,否则新建一个事务)、PROPAGATION_...
Spring事务管理是企业级Java应用中不可或缺的一部分,它确保了数据的一致性和完整性,尤其是在多线程和分布式环境中。本实例将深入探讨Spring事务管理的实现与应用。 首先,Spring事务管理分为编程式事务管理和声明...