转:spring事务控制配置实例
Spring声明式事务配置的几种方法
在Spring中进行事务控制首先要选择适当的事务管理器,其次为程序选择划分事务的策略。如果只有单个事务性资源,可以从“单一资源”的PlatformTransactionManger实现当中选择一个,这些实现有:DataSourceTransactionManager,HibernateTransactionManager, JdoTransactionManager,PersistenceBrokerTransactionManager和JmsTransactionManager。根据你所采用的数据库持久化技术选择。如果你的项目运行于支持JTA的服务器,那么将选择JtaTransactionManger,将会支持多资源事务。
下表将为你选择适当的事务管理器提供参考。
技术 事务管理器(————后) 内建的事务支持(括号内)
JDBC————DataSurceTransactionManager
JtaTransactionManager
(JdbcTemplate和org.springframework.jdbc.object包中的所有类 )
IBATIS————DataSourceTransactionManager
JtaTransactionManager
(SqlMapClientTemplate和SqlClientTemplate)
Hibernate————HibernateTransactionManager
JtaTransactionManager
(HibernateTemplate和HibernateInterceptor)
JDO————JdoTransactionManager
JtaTransactionManager
(JdoTemplate和JdoInterceptor)
ApacheOJB————PersistenceBrokerTransactionManager
JtaTransactionManager
(PersistenceBrokerTemplate)
JMS————JmsTransactionManager
(JmsTemplate)
在划分事务时,我们需要进行事务定义,也就是配置事务的属性。事务的属性有传播行业,隔离级别,超时值及只读标志。TransactionAttribute接口指定哪些异常将导致一个回滚,哪些应该一次性提交。
(1) 使用ProxyFactoryBean 和TransactionInterceptor
<!--定义本地数据源-->
<bean id="dataSource" name="dataSource" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- !定义单个jdbc数据源的事务管理器-->
<bean id="transactionManager" ref="dataSource"/>
</bean>
<!—定义拦截器-->
<bean id="transactionInterceptor"
ref="com.prs.application.ehld.sample.integration.dao.userInfoDAO">
</property>
</bean>
<!—定义业务对象的事务代理对象-->
<bean id="com.prs.application.ehld.sample.biz.service.sampleService"
ref="com.prs.application.ehld.sample.biz.service.sampleService.target">
</property>
<property name="interceptorNames">
<value>transactionInterceptor</value>
</property>
</bean>
通过ProxyFacgtoryBean和TransactionInterceptor组合使用,可以对事务进行更多的控制。所有需要事务控制的对象可以共享一个transactionInterceptor的事务属性。
(2) 使用TransactionProxyFactoryBean
<!—定义业务对象-->
<bean id="com.prs.application.ehld.sample.biz.service.sampleService.target"
ref="com.prs.application.ehld.sample.integration.dao.userInfoDAO">
</property>
</bean>
<!—定义业务对象的事务代理对象-->
<bean id="com.prs.application.ehld.sample.biz.service.sampleService"
ref="com.prs.application.ehld.sample.biz.service.sampleService.target" />
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="*">PROPAGATION_SUPPORTS,readOnly</prop>
</props>
</property>
</bean>
使用TransactionProxyFactoryBean需要为每一个代理对象都去定义自己的事务属性。
(3) 使用TransactionProxyFactoryBean及abstract属性来简化配置
这种方工也是目前使用得最多的一种声明式事务配置方法
<!--事务控制代理抽象定义 -->
<bean id="baseTransactionProxy"
ref="com.prs.application.ehld.sample.integration.dao.userInfoDAO">
</property>
</bean>
<!—定义业务对象的事务代理对象-->
<bean id="com.prs.application.ehld.sample.biz.service.sampleService" parent="baseTransactionProxy">
<property name="target"
ref="com.prs.application.ehld.sample.biz.service.sampleService.target">
</property>
</bean>
使用abstract属性,可以让代理对象可以共享一个定义好的事务属性,使配置简化。
(4)使用BeanNameAutoProxyCreator
<!—定义拦截器-->
<bean id="transactionInterceptor"
ref="com.prs.application.ehld.sample.integration.dao.userInfoDAO">
</property>
</bean>
2 楼 TeddyWang 2011-01-12 现在基本已经不这么做了,你把问题说详细。