上篇我们学习了Spring.NET的事务机制。回顾一下,实现事务需要在方法上标记[Transaction]。在很多情况下,事务往往与业务分离。Spring.NET提供了事务代理帮我们管理这些事务,我们可以通过TransactionProxyFactoryObject使用声明式事务。在很多情况下TransactionProxyFactoryObject比ProxyFactoryObject易用,因为该类可以通过自身属性来指定事务通知和事务特性,所以不需要单独为事务通知定义对象。另外,与使用ProxyFactoryObject不同,TransactionProxyFactoryObject不要求使用方法的全名,只用普通的“短”方法名即可。同时,该类可以对方法名进行wild card matching,从而强制我们为DAO的方法使用统一命名规则。
TransactionProxyFactoryObject的TransactionAttributes属性是用来配置的传播行为,并规定了7种类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:
PROPAGATION_REQUIRED | 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。 |
PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行。 |
PROPAGATION_MANDATORY | 支持当前事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常。 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。 |
PROPAGATION_REQUIRED和PROPAGATION_SUPPORTS我用的比较多,其它的很少使用。特别是PROPAGATION_REQUIRED,我绝大多数情况都使用这个行为(如,在创建,删除,修改的时候),我会在查询(获取)数据的时候设置为:PROPAGATION_REQUIRED,readOnly,声明为一个只读事务,这样有助于性能的提高。
TransactionProxyFactoryObject的Target属性是我们要拦截的对象,一般我们设置为业务层的对象。
实现代码:
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
<?xml version="1.0" encoding="utf-8" ?>
< objects xmlns ="http://www.springframework.net"
xmlns:db ="http://www.springframework.net/database" >
< db:provider id ="DbProvider"
provider ="SqlServer-1.1"
connectionString ="Server=(local);Database=SpringLesson16;Uid=sa;Pwd=;Trusted_Connection=False" />
< object id ="userDao" type ="Dao.UserDao, Dao" >
< property name ="AdoTemplate" ref ="adoTemplate" />
</ object >
< object id ="accountDao" type ="Dao.AccountDao, Dao" >
< property name ="AdoTemplate" ref ="adoTemplate" />
</ object >
< object id ="userService" parent ="txProxyTemplate" >
< property name ="Target" >
< object type ="Service.UserService, Service" >
< property name ="UserDao" ref ="userDao" />
< property name ="AccountDao" ref ="accountDao" />
</ object >
</ property >
</ object >
< object id ="adoTemplate" type ="Spring.Data.Core.AdoTemplate, Spring.Data" >
< property name ="DbProvider" ref ="DbProvider" />
< property name ="DataReaderWrapperType" value ="Spring.Data.Support.NullMappingDataReader, Spring.Data" />
</ object >
<!-- 事务管理器 -->
< object id ="transactionManager"
type ="Spring.Data.Core.AdoPlatformTransactionManager, Spring.Data" >
< property name ="DbProvider" ref ="DbProvider" />
</ object >
< object id ="txProxyTemplate" abstract ="true"
type ="Spring.Transaction.Interceptor.TransactionProxyFactoryObject, Spring.Data" >
< property name ="PlatformTransactionManager" ref ="transactionManager" />
< property name ="TransactionAttributes" >
< name-values >
< add key ="Save*" value ="PROPAGATION_REQUIRED" />
< add key ="Delete*" value ="PROPAGATION_REQUIRED" />
< add key ="Get*" value ="PROPAGATION_REQUIRED,readOnly" />
</ name-values >
</ property >
</ object >
</ objects >
在name-value节点下,key属性为Save*,意思是拦截所有以Save开头的方法,在拦截到的方法上增加PROPAGATION_REQUIRED的事务传播行为。