
文章插图
摘要Spring框架是一个流行的基于轻量级控制反转容器的JAVA/J2EE应用框架,尤其在数据访问和事务管理方面的能力是众所周知的 。Spring的声明性事务分离可以应用到任何POJO目标对象,并且包含所有EJB基于容器管理事务中的已声明事务 。后台的事务管理器支持简单的基于JDBC的事务和全功能的基于JTA的J2EE事务 。
这篇文章详细的讨论了Spring的事务管理特性 。重点是如何在使用JTA作为后台事务策略的基础上让POJO利用Spring的声明性事务,这也显示了Spring的事务服务可以无缝地与J2EE服务器(如BEA WebLogic Server的事务协调器)的事务协调器进行交互,作为EJB CMT传统事务分离方式的一个替代者 。

文章插图
POJO的声明性事务作为Spring声明性事务分离方式的样例,让我们来看一下Spring的样例应用PetClinic的中心服务外观中的配置:
清单1:
<bean id="dataSource"class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:comp/env/jdbc/petclinic</value> </property></bean><bean id="transactionManager"class="org.springframework.transaction.jta.JtaTransactionManager"/><bean id="clinicTarget"class="org.springframework.samples.petclinic.jdbc.JdbcClinic"> <property name="dataSource"><ref bean="dataSource"/></property></bean><bean id="clinic"class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"><ref bean="transactionManager"/></property> <property name="target"><ref bean="clinicTarget"/></property> <property name="transactionAttributes"> <props> <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="store*">PROPAGATION_REQUIRED</prop> </props> </property></bean>他遵循Spring的标准XMLBean定义格式 。定义了:
- 一个DataSource引用,指向一个JNDI位置—在J2EE服务器管理下这将从JNDI环境中获取特定的DataSource 。
- 一个应用服务实现—这是一个POJO,封装了业务和数据访问逻辑 。在这里实现了应用中的Clinic服务接口 。
- 一个应用服务的事务代理—这个代理为目标服务定义了事务属性,匹配特定的方法名模式并为之创建相应的事务 。在实际的事务管理中,代理指向一个PlatformTransactionManager实现 。
业务接口和业务实现是特定于应用的并且不需要关心Spring或者Spring的事务管理 。普通Java对象可以作为服务的目标对象,而且任何普通Java接口可以作为服务的接口 。下面是一个Clinic接口的示例:
清单2:
public interface Clinic { Pet loadPet(int id); void storePet(Pet pet); ...}这个接口的实现如下显示,假设他使用JDBC来执行必要的数据访问 。他通过bean属性的设置方法来获取JDBC的DataSource;这与上面的配置中的dataSource属性定义相对应 。
清单3:
public class JdbcClinic implements Clinic { private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public Pet loadPet(int id) { try { Connection con = this.dataSource.getConnection(); ... } catch (SQLException ex) { ... } } public void storePet(Pet pet) { try { Connection con = this.dataSource.getConnection(); ... } catch (SQLException ex) { ... } } ...}如你所见,代码相当直接 。我们使用一个简单的Java对象,而事务管理由事务代理来处理,这个我们会在下面讨论 。
注意在PetClinic示例应用中实际的基于JDBC的Clinic实现利用了Spring的JDBC支持类来避免直接使用JDBC的API 。虽然Spring的事务管理也可以与普通的基于JDBC实现一起工作,就向上面的示例 。
定义事务代理除了JdbcClinic实例以外,配置中也定义了一个事务代理 。如果愿意这个代理所暴露的实际接口也可以显式定义 。默认情况下,所有由目标对象实现的接口都暴露出来,在这个例子中就是应用的Clinic服务接口 。
从客户端的观点来看,"clinic" bean只是这个应用的Clinic接口的实现 。客户端不需要知道这会被一个事务代理所处理 。这就是接口的能力:一个直接的目标对象的引用可以容易的被一个实现相同接口的代理所代替—在这儿就是一个隐式创建事务的代理 。
推荐阅读
- Android系统架构浅析
- Android MVP 架构介绍与使用入门
- 阿里云ECS服务器被挖矿怎么解决
- 招财鱼风水命理和摆放详解
- 高山茶和阿里山的姑娘
- 华为P30pro偏光分离+贴合技术详解
- 慢品功夫茶 功夫茶茶艺8大步骤详解
- 阿里架构总监13张PPT一次讲透中台架构
- B/S架构web请求过程详解
- 阿里云虚拟主机配置ssl加密链接
