Spring声明式事务管理

转自http://book.51cto.com/art/200808/87197.htm

通常建议采用声明式事务管理。声明式事务管理的优势非常明显,代码中无须关注事务逻辑,由 Spring 声明式事务管理负责事务逻辑:声明式事务管理无须与具体的事务逻辑糯合,可以方便地在不同事务逻辑之间切换。

声明式事务管理的配置方式通常有如下四种。

使用 TransactionProxyFactoryBean 为目标 bean 生成事务代理的配置。此方式最传统,但配置文件膝肿,难以阅读。

采用 bean 继承的事务代理配置方式比较简沽,但依然是增量式配置。

使用 BeanNameAutoProxyCreator ,根据 bean name 自动生成事务代理的方式,这是直接利用 Spring 的 AOP 框架配置事务代理的方式,需要对 Spring 的 AOP 框架有所理解,但这种方式避免了增量式配置,效果非常不错。

DefaultAdvisorAutoProxyCreator: 这也是直接利用 Spring 的 AOP框架配置事务代理的方式,效果也非常不错,只是这种配置方式的可读性不如第三种方式。

1. 利用 TransactionProxyFactoryBean 生成事务代理

采用这种方式的配置时,其配置文件的增加非常快,每个 bean 有需要两个 bean 配置一个目标,另外还需要使用 TransactionProxyFactoryBean 配置一个代理 bean。这是一种最原始的配置方式,下面是使用 TransactionProxyFactoryBean 的配置文件:

在上面的配置文件中,personDao需要配置两个部分:一个是personDao的目标bean,该目标bean是实际DAO bean,以实际的DAO bean为目标,建立事务代理;另一个是组件,需要一个目标bean和一个事务代理来组成。

但这种配置方式还有一个缺点:目标bean 直接暴露在 Spring 容器中,可以直接引用,如果目标bean被误引用,将导致业务操作不具备事务性。

为了避免这种现象,可将目标bean配置成嵌套bean, ~面是目标bean和事务代理的配置代码:

2. 利用继承简化配置

大部分情况下,每个事务代理的事务属性大同小异,事务代理的实现类都是TransactionProxyFactoryBean,事务代理bean都必须注入事务管理器。

对于这种情况, Spring 提供了 bean 与 bean之间的继承,可以简化配置。将大部分通用的配置,配置成事务模板,而实际的事务代理bean,则继承事务模板。这种配置方式可以减少部分配置代码。下面是采用继承的配置文件:

相比前面直接采用TransactionProxyFactoryBean 的事务代理配置方式,这种配置方式可以大大减少配置文件的代码量。每个事务代理的配置都继承事务模板,无须重复指定事务代理的实现类,也无须重复指定事务传播属性。但如果新的事务代理有额外的事务属性,也可指定自己的事务属性,此时,子 bean 的属性覆盖父 bean 的属性。当然每个事务代理 bean 都必须配置自己的目标 bean,这是不可避免的。

从上面的配置可看出,事务代理的配置依然是增量式的,每个事务代理都需要单独配置。

3. 用 BeanNameAutoProxyCreator 自动创建事务代理

下面介绍-种优秀的事务代理配置策略,采用这种配置策略,完全可以避免增量式配置,使所有的事务代理由系统自动创建。由于容器中的目标bean 自动消失,可避免需要使用嵌套 bean 来保证目标 bean 不可被访问。

这种配置方式依赖于 Spring 提供的 bean 后处理器,该后处理器用于为每个 bean 自动创建代理,此处的代理不仅可以是事务代理,也可以是任意的代理,只需要有合适的拦截器即可。这些是 AOP 框架的概念,笔者在此处不对 AOP 进行深入介绍。读者只需了解这种事务代理的配置方式即可。

下面是采用 BeanNameAutoProxyCreator 配置事务代理的配置文件:

TranscationInterceptor是一个事务拦截器bean,需要传入一个Transaction~anager的引用。配置中使用 Spring 依赖注入该属性,事务拦截器的事务属性通过transactionAttributes来指定,该属性有props子元素,并在配置文件中定义了三个事务传播规则。所有以 insert 开始的方法,都采用PROPAGATION_REQUIRED的事务传播规则。

当程序抛出~yException异常及其子异常时,会自动回滚事务:所有以find开头的方法,都采用 PROPAGATION_REQUIRED事务传播规则,并且具有只读性;其他方法则采用PROPAGATION_REQUIRED的事务传播规则。

BeanNameAutoProxyCreator是根据 bean名生成自动代理的代理创建器,该bean通常需要接受两个参数:第一个是beanNames属性,该属性用来设置哪些bean 需要自动生成代理,另一个属性是interceptorNames,该属性则指定事务拦截器,在自动创建事务代理时,系统会根据这些事务拦截器的属性来生成对应的事务代理。

为了让读者对这种配置方式有信息,可对PersonDaoHibemate的 save方法进行简单修改,修改后的save方法如下:

在主程序中调用该save方法,主程序调用save方法的代码如下:

执行完主程序的该片段后,数据库不会插入任何记录。如果BeanNameAutoProxyCreator的配置修改成如下格式:

注意配置文中beanNames属性的变化,将所有personDao项加注释,即不再为该bean生成事务代理。再次执行主程序,此时程序虽然抛出了数据库异常,但数据记录依然被插入数据库。

这种配置方式相当简洁,每次都增加了新的bean。如果需要该bean 的方法具有事务性,只需在BeanNameAutoProxyCreator的 beanNames 属性下作相应修改。该行告诉bean后处理需要为哪个bean生成事务代理。

4. 用 DefaultAdvisorAutoProxyCreator自动创建事务代理

这种配置方式与BeanNameAutoProxyCreator自动创建代理的方式非常相似,都是使用 bean 后处理器为目标bean创建实物代理。区别是前者使用事务拦截器创建代理;后者需要使用Advisor创建事务代理。

事实上,采用DefaultAdvisorAutoProxyCreator的事务代理配置方式更加简洁,因为这个代理生成器自动搜索Spring 容器中的Advisor,并为容器中所有的bean创建代理。相对前一种方式,这种方式的可读性不如前一种直观,笔者还是推荐采用第三种配置方式,下面是使用DefaultAdvisorAutoProxyCreator的配置方式:

在这种配置方式下,配置文件变得更加简沽,增加目标bean 时不需要增加任何额外的代码,容器会自动为目标bean生成代理。但这种方式的可读性相对较差。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值