- 浏览: 263930 次
- 性别:
- 来自: 天津
文章分类
- 全部博客 (180)
- J2SE (15)
- J2EE (7)
- Struts (2)
- Hibernate (18)
- Spring (22)
- ssh (2)
- HTML (1)
- JS (10)
- CSS (3)
- jQuery (15)
- extJS (0)
- FLEX (14)
- Web service (7)
- Axis2 (3)
- lucene2.0 (9)
- maven (3)
- JBoss (0)
- WebLogic (0)
- Linux (8)
- Android (0)
- SiteMesh (1)
- JPA (0)
- JBPM (1)
- xFire (3)
- XML (4)
- apache (4)
- bingo专区 (0)
- 加密解密算法研究 (1)
- 数据库 (16)
- 资料 (1)
- 经验 (4)
- 健康 (1)
- 技术交流区 (1)
- 交友区 (0)
- jquery 插件区 (1)
最新评论
-
forrest_lv:
很有帮助
Axis2 XFire CXF 比较 -
kuloujianzun:
...
flex DataGrid -
zx.peng:
大哥,请教一下...
下面在别的地方引入:(在什么地方、怎么 ...
FLEX下拉多选框 -
elvislee030:
试试去,正好要找这个组件。。先谢过
FLEX下拉多选框 -
futrueboy:
如果你发到网上来,请翻译的好点
Apache Mina的学习应用(三)
三.用BeanNameAutoProxyCreator自动创建事务代理
下面介绍一种优秀的事务代理配置策略:采用这种配置策略,完全可以避免增量式配置,所有的事务代理由系统自动创建。容器中的目标bean自动消失,避免需要使用嵌套bean来保证目标bean不可被访问。
这种配置方式依赖于Spring提供的bean后处理器,该后处理器用于为每个bean自动创建代理,此处的代理不仅可以是事务代理,也可以是任意的代理,只需要有合适的拦截器即可。这些是AOP框架的概念,笔者在此处不对AOP进行深入介绍。读者只需了解这种事务代理的配置方式即可。
下面是采用BeanNameAutoProxyCreator配置事务代理的配置文件:
<?xml version="1.0" encoding="gb2312"?>
<!-- Spring配置文件的文件头,包含DTD等信息-->
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--定义数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 定义数据库驱动-->
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<!-- 定义数据库url-->
<property name="url"><value>jdbc:mysql://localhost:3306/spring</value></property>
<!-- 定义数据库用户名-->
<property name="username"><value>root</value></property>
<!-- 定义数据库密码-->
<property name="password"><value>32147</value></property>
</bean>
<!--定义一个hibernate的SessionFactory-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 定义SessionFactory必须注入DataSource-->
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<!--以下用来列出所有的PO映射文件-->
<value>Person.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<!--此处用来定义hibernate的SessionFactory的属性:
不同数据库连接,启动时选择create,update,create-drop-->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- 定义事务管理器,使用适用于Hibernte的事务管理器-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<!-- HibernateTransactionManager bean需要依赖注入一个SessionFactory bean的引用-->
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<!-- 配置事务拦截器-->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!-- 事务拦截器bean需要依赖注入一个事务管理器 -->
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<!-- 下面定义事务传播属性-->
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 定义BeanNameAutoProxyCreator,该bean是个bean后处理器,无需被引用,因此没有id属性
这个bean后处理器,根据事务拦截器为目标bean自动创建事务代理
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
指定对满足哪些bean name的bean自动生成业务代理 -->
<property name="beanNames">
<!-- 下面是所有需要自动创建事务代理的bean-->
<list>
<value>personDao</value>
</list>
<!-- 此处可增加其他需要自动创建事务代理的bean-->
</property>
<!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器-->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
<!-- 此处可增加其他新的Interceptor -->
</list>
</property>
</bean>
<!--定义DAO Bean ,由于BeanNameAutoProxyCreator自动生成事务代理-->
<bean id="personDao" class="lee.PersonDaoHibernate">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
</beans>
TranscationInterceptor是一个事务拦截器bean,需要传入一个TransactionManager的引用。配置中使用Spring依赖注入该属性,事务拦截器的事务属性通过transactionAttributes来指定,该属性有props子元素,配置文件中定义了三个事务传播规则:
所有以insert开始的方法,采用PROPAGATION_REQUIRED的事务传播规则。程序抛出MyException异常及其子异常时,自动回滚事务。所有以find开头的方法,采用PROPAGATION_REQUIRED事务传播规则,并且只读。其他方法,则采用PROPAGATION_REQUIRED的事务传播规则。
BeanNameAutoProxyCreator是个根据bean名生成自动代理的代理创建器,该bean通常需要接受两个参数。第一个是beanNames属性,该属性用来设置哪些bean需要自动生成代理。另一个属性是interceptorNames,该属性则指定事务拦截器,自动创建事务代理时,系统会根据这些事务拦截器的属性来生成对应的事务代理。
为了让读者对这种配置方式有信息,对PersonDaoHibernate的save方法进行简单修改,修改后的save方法如下:
public void save(Person person)
...{
getHibernateTemplate().save(person);
//下面两行代码没有实际意义,仅仅为了引发数据库异常
DataSource ds = null;
DataSourceUtils.getConnection(ds);
}
在主程序中调用该save方法,主程序调用save方法的片段如下:
...{
//保存Person实例
pdao.save(new Person(String.valueOf(i) , i + 10));
}
执行完主程序的该片段后,数据表不会插入任何记录。如果BeanNameAutoProxyCreator的配置修改成如下格式:
这个bean后处理器,根据事务拦截器为目标bean自动创建事务代理
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
指定对满足哪些bean name的bean自动生成业务代理 -->
<property name="beanNames">
<!-- 下面是所有需要自动创建事务代理的bean-->
<list>
<!-- value>personDao</value-->
</list>
<!-- 此处可增加其他需要自动创建事务代理的bean-->
</property>
<!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器-->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value >
<!-- 此处可增加其他新的Interceptor -->
</list>
</property>
</bean>
注意配置文中beanNames属性的变化,将所有personDao项注释,即不再为该bean生成事务代理。再次执行主程序,程序虽然抛出了数据库异常,但数据记录依然被插入数据库。
对比两次结果,这就是事务代理在其中的作用。
这种配置方式相当简洁,每次增加了新的bean,如果需要该bean的方法具有事务性,只需在BeanNameAutoProxyCreator的beanNames属性下增加一行即可,该行告诉bean后处理需要为哪个bean生成事务代理。
四. 用DefaultAdvisorAutoProxyCreator自动创建事务代理
这种配置方式与BeanNameAutoProxyCreator自动创建代理的方式非常相似,都是使用bean后处理器为目标bean创建实物代理,区别是前者使用事务拦截器创建代理,后者需要使用Advisor创建事务代理。
事实上,采用DefaultAdvisorAutoProxyCreator的事务代理配置方式更加简洁,这个代理生成器自动搜索Spring容器中的Advisor,并为容器中所有的bean创建代理。
相对前一种方式,这种方式的可读性不如前一种直观,笔者还是推荐采用第三种配置方式,下面是使用DefaultAdvisorAutoProxyCreator的配置方式:
<!-- Spring配置文件的文件头,包含DTD等信息-->
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--定义数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 定义数据库驱动-->
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<!-- 定义数据库url-->
<property name="url"><value>jdbc:mysql://localhost:3306/spring</value></property>
<!-- 定义数据库用户名-->
<property name="username"><value>root</value></property>
<!-- 定义数据库密码-->
<property name="password"><value>32147</value></property>
</bean>
<!--定义一个hibernate的SessionFactory-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<!-- 定义SessionFactory必须注入DataSource-->
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<!--以下用来列出所有的PO映射文件-->
<value>Person.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<!--此处用来定义hibernate的SessionFactory的属性:
不同数据库连接,启动时选择create,update,create-drop-->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<!-- 定义事务管理器,使用适用于Hibernte的事务管理器-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<!-- HibernateTransactionManager bean需要依赖注入一个SessionFactory bean的引用-->
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<!-- 配置事务拦截器-->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!-- 事务拦截器bean需要依赖注入一个事务管理器 -->
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributes">
<!-- 下面定义事务传播属性-->
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 定义事务Advisor-->
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
<!-- 定义advisor时,必须传入Interceptor-->
<property name="transactionInterceptor" ref="transactionInterceptor"/>
</bean>
<!-- DefaultAdvisorAutoProxyCreator搜索容器中的 advisor,并为每个bean创建代理 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<!--定义DAO Bean ,由于BeanNameAutoProxyCreator自动生成事务代理-->
<bean id="personDao" class="lee.PersonDaoHibernate">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
</beans>
在这种配置方式下,配置文件变得更加简洁,增加目标bean,不需要增加任何额外的代码,容器自动为目标bean生成代理。但这种方式的可读性相对较差。
事务传播行为种类
Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:
表1事务传播行为类型
事务传播行为类型 |
说明 |
PROPAGATION_REQUIRED |
如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 |
PROPAGATION_SUPPORTS |
支持当前事务,如果当前没有事务,就以非事务方式执行。 |
PROPAGATION_MANDATORY |
使用当前的事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW |
新建事务,如果当前存在事务,把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED |
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NEVER |
以非事务方式执行,如果当前存在事务,则抛出异常。 |
PROPAGATION_NESTED |
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。 |
当使用PROPAGATION_NESTED时,底层的数据源必须基于JDBC 3.0,并且实现者需要支持保存点事务机制。
<!--Hibernate事务管理器-->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
<!-- 定义事务拦截器bean-->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!-- 事务拦截器bean需要依赖注入一个事务管理器-->
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<!-- 下面定义事务传播属性-->
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="managerTemplate" abstract="true" lazy-init="true">
<property name="teamDao">
<ref bean="teamDao" />
</property>
<property name="studentDao">
<ref bean="studentDao" />
</property>
</bean>
<bean id ="manager" class="com.zd.service.impl.Manager" parent="managerTemplate" />
<!-- 定义BeanNameAutoProxyCreator-->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!-- 指定对满足哪些bean name的bean自动生成业务代理 -->
<property name="beanNames">
<!-- 下面是所有需要自动创建事务代理的bean-->
<list>
<value>manager</value>
</list>
<!-- 此处可增加其他需要自动创建事务代理的bean-->
</property>
<!-- 下面定义BeanNameAutoProxyCreator所需的事务拦截器-->
<property name="interceptorNames">
<list>
<!-- 此处可增加其他新的Interceptor -->
<value>transactionInterceptor</value>
</list>
</property>
</bean>
<!-- 基本数据库操作 -->
<bean id="baseDao" class="com.zd.service.impl.BaseDao">
<property name="hibernateTemplate">
<ref bean="hibernateTemplate"/>
</property>
</bean>
<!-- 班级 -->
<bean id="teamDao" class="com.zd.service.impl.TeamDao">
<property name="baseDao">
<ref bean="baseDao" />
</property>
</bean>
<!-- 学生 -->
<bean id="studentDao" class="com.zd.service.impl.StudentDao">
<property name="baseDao">
<ref bean="baseDao" />
</property>
</bean>
public void testSaveTeam() {
Team team = new Team();
team.setTeamId(DBKeyCreator.getRandomKey(12));
team.setTeamName("Class CCC");
IManager manager = (IManager) SpringContextUtil.getContext().getBean("manager");
Student student = new Student();
student.setStudentId(DBKeyCreator.getRandomKey(13));
student.setSex(Student.SEX_FEMALE);
student.setStudentName("Tom");
student.setTeamId("60FHDXDIG5JQ");
manager.saveTeamAndStu(team, student);
System.out.println("Save Team and Student Success");
}
发表评论
-
Spring 企业级开发应用---------AXIS和spring的远程服务整合的应用
2010-08-16 14:36 1184Spring框架对远程访问 ... -
Spring 企业级开发应用---------httpinvoke和spring的远程服务整合的应用
2010-08-16 14:35 964和burlap和hessian一样的配置细细 服务端服务 ... -
Spring 企业级开发应用---------hessian和spring的远程服务整合的应用
2010-08-16 14:35 941hessian和burlap使用同一公司的产品实现机制不同 ... -
Spring 企业级开发应用---------burlap和spring的远程服务整合的应用
2010-08-16 14:34 856使用burlap和spring整合发布远程服务 开发步骤 ... -
Spring 企业级开发应用---------rmi和spring的整合的应用
2010-08-16 14:34 832使用spring和rmi开发远程服务的类的应用(此处可以一 ... -
spring2.5 和Hibernate的注解的应用
2010-08-16 14:30 799一、步骤 a. <!-- 数据源 --&g ... -
获取ApplicationContext的几种方式
2010-08-16 14:26 984第一种采用类路径的加载方式获取: Appli ... -
Spring 注解的配置的细节
2010-08-16 14:16 1709一. spring注解 1.准备工作(1)导入comm ... -
使用Spring 2.5 注释驱动的 IoC 功能
2010-08-16 14:10 860在项目中使用Spring的注解,关于sp ... -
Spring 和ActionMQ整合JMS开发应用
2010-08-16 13:51 1522Spring 和ActionMQ整合 ... -
Spring中添加 Log4j注解
2010-08-16 13:49 2508参照别人的代码做了个Demo如下: Spring的加载时 ... -
Spring 的优秀工具类盘点,特殊字符转义和方法入参检测工具类
2010-08-16 13:46 997Spring 不但提供了一个功能全面的应用开发框架,本身还 ... -
Spring Web 相关工具类
2010-08-16 13:38 1015Web 相关工具类 您几乎总是使用 Spring 框架开 ... -
Spring 的优秀工具类盘点
2010-08-16 13:22 769Spring 不但提供了一个功能全面的 ... -
Spring ApplicationContext.xml配置的12个技巧
2010-08-16 13:08 1260Spring是一个强有力的ja ... -
Spring 中一个常用的反射类库ReflectionUtils
2010-08-16 13:05 4402在项目中部分方法采用反射,通过类访问类的属性,通过类反问方法, ... -
spring 的OpenSessionInViewFilter简介
2010-08-16 11:39 611假设在你的应用中Hibernate是通过spring 来管 ... -
使用hibernate3和Spring解决Oracle大字段(长文本)问题
2010-08-16 11:33 1470使用Oracle来存储长文本始终没Mysql ... -
Spring中Quartz的配置
2009-11-02 09:56 672Quartz是一个强大的企业级任务调度框架,Spring中继承 ... -
使用Spring2.5的Autowired实现注释型的IOC
2009-11-01 21:10 1004使用Spring2.5的新特性——Autowired可以实现 ...
相关推荐
在"spring声明式事务管理配置方式"中,主要涉及到以下几个关键知识点: 1. **Spring事务管理器(Transaction Manager)**: - Spring支持多种事务管理器,如DataSourceTransactionManager(用于JDBC事务)和...
Spring声明式事务配置管理方法
在整个源代码分析中,我们可以看到 Spring 实现声明式事务管理有三个部分: 1. 对在上下文中配置的属性的处理,这里涉及的类是 TransactionAttributeSourceAdvisor,这是一个通知器,用它来对属性值进行处理,属性...
文件名为`Spring声明式事务处理-1.mht`到`Spring声明式事务处理-5.mht`,通过阅读这些文件,你将能够深入理解Spring声明式事务处理的各个方面,包括配置、使用场景、最佳实践以及常见问题的解决方法。
在这个"spring声明式事务处理demo"中,我们将探讨如何在MyEclipse环境下实现这一功能。 首先,我们要理解Spring事务管理的两种主要方式:编程式事务管理和声明式事务管理。编程式事务管理通常通过AOP(面向切面编程...
实验 "Spring 声明事务" ...通过这个实验,学生可以深入理解Spring声明式事务管理的工作原理,以及如何在实际项目中配置和使用。这将有助于他们在未来开发中更好地处理事务相关的复杂问题,确保应用程序的数据一致性。
本文将全面分析Spring中的编程式事务管理和声明式事务管理,旨在帮助开发者深入理解这两种事务管理方式,并在实际项目中合理选择。 **编程式事务管理** 编程式事务管理是通过代码直接控制事务的开始、提交、回滚等...
### 标题解读:Spring声明式事务配置 Spring框架提供了两种主要类型的事务管理方式:编程式事务管理和声明式事务管理。声明式事务管理通过XML配置或注解的形式定义事务边界,使得业务逻辑与事务控制分离。 ### ...
本文将详细解释 Spring 的编程式事务管理及声明式事务管理,帮助读者理清思路。 事务管理的重要性 事务管理对于企业应用至关重要。它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏...
spring声明式事务管理+jdbc+连接池 包内为代码,下载可直接执行。 一直用s2sh,感觉hibernate不好用,所以写了一个spring声明式事务管理+jdbc+连接池。
本资料包"spring声明式事务管理+jdbc+连接池.zip"显然是针对Spring框架在数据库操作方面的深入学习,特别是如何利用Spring进行声明式事务管理和JDBC操作,以及如何配置和使用数据库连接池。接下来,我们将详细探讨这...
Spring提供两种事务管理方式:编程式事务管理和声明式事务管理。编程式事务管理通过编写代码来控制事务的开始、提交、回滚等操作,灵活性高但侵入性强。相比之下,声明式事务管理则更加简洁,它通过配置或注解来...
spring声明式事务管理_入门
本教程将深入探讨 Spring 的编程式事务管理和声明式事务管理,帮助你理解这两种方式的差异与应用场景。 首先,编程式事务管理依赖于编程的方式显式地控制事务的开始、提交、回滚等操作。它通过实现 `...
1.掌握Myeclipse的使用。 2.掌握spring框架和hibernate框架的使用。 3. 掌握整合spring和hibernate的持久化操作编程 4.掌握基于AOP的声明式事务编程...3.配置WEB-INF/applicationContext.xml提供基于AOP的声明式事务
在Java应用中,Spring提供了两种主要的事务管理方式:编程式事务管理和声明式事务管理。 **编程式事务管理** 是通过调用`PlatformTransactionManager`接口提供的方法来手动控制事务的开始、提交、回滚。例如,你...
在Spring框架中,声明式事务管理是实现事务处理...在博文"Spring使用XML配置声明式事务"中,作者详细讲解了每个步骤,并可能通过示例代码展示了如何实际应用这些配置,帮助读者更好地理解和掌握Spring声明式事务管理。