聊聊Spring事务管理

来源:互联网 发布:ff14 npc捏脸数据库 编辑:程序博客网 时间:2024/06/06 22:37

这里写图片描述

这里写图片描述

如上所言,事务遵循ACID原则,A是原子性(atomicity);B是一致性(consistency),事务执行前后涉及到的相关数据保持一致;C是隔离性(isolation),事务正确提交之前结果不应被其他事务所见;D是持久性(durability),执行结果得到持久保存。这对于金融系统和交易类业务处理系统至关重要。

面向单一事务资源(数据库或应用服务)的称之为本地事务,java可通过JDBC的Connection实现;面向多个事务资源的分布式同步管理的称之为全局事务,java可通过JTA按照XA的二阶段提交方式实现。

这里写图片描述

Spring事务管理框架对JDBC、JTA事务处理进行了更高一层抽象,向开发人员提供了统一的开发接口,面对本地事务和全局事务使用一种编程模型,从而大大降低了开发的复杂度。

在开发中使用spring进行事务管理,需要首先在配置文件中进行transactionManager的配置,然后通过编程方式或者声明方式调用事务处理。

这里写图片描述

  • 本地事务
    基于JDBC事务管理器配置示例如下:
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        <property name="dataSource" ref="dataSource" /></bean>
  • 1
  • 2
  • 3

dataSource属性指定需要事务管理的javax.sql.DataSource对象。

  • 全局事务
    大部分应用服务器容器提供JTA支持,配置好JNDI数据源和JtaTransactionManager即可。
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:jee="http://www.springframework.org/schema/jee"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">    <jee:jndi-lookup id="dataSource" jndi-name="jdbc/test" />    <bean id="transactionManager" class="org.springframework.transication.JtaTransactionManager">        <property name="transactionManagerName" value="java:comp/TransactionManager" />    </bean></beans>

dataSource“表示从JNDI中获取数据源,”transactionManager“是JTA事务管理器,其中属性transactionManagerName是其JNDI命名。

Spring还提供了对特定应用服务器事务管理器集成的支持,如:WebLogicJtaTransactionManagerWebSphereUowTransactionManagerOC4JJtaTransactionManager

Tomcat容器本身不支持JTA,但可以借助于第三方JTA管理器实现,如JOTM(Java Open Transaction Manager )或AtomikosTransactionsEssentials

这里写图片描述

应用需要调用Spring提供的PlatformTransactionManagerTransactionDefinitionTransactionStatus 三个核心接口。下面以银行账户之间转账例子说明。

public class BankServiceImpl implements BankService {    private BankDao bankDao;    private TransactionDefinition txDefinition;    private PlatformTransactionManager txManager;    public boolean transfer(long fromId, long toId, BigDecimal amount){        Transaction txStatus = txManager.getTransaction(txDefinition);        boolean result = false;        try{            result = bankDao.transfer(fromId, toId, amount);            txManager.commit(txStatus);        } catach(){            result = false;            txManager.rollback(txStatus);        }        return result;    }}

此外,Spring还提供了更为简化的TransactionTemplate开发接口。

这里写图片描述

声明式通过配置或注解方式将事务管理与业务逻辑代码独立,开发人员只需在配置文件中做相应的事务规则声明或注解,便可以将事务规则通过AOP横切应用到业务逻辑中。支持TransactionInterceptorTransactionProxyFactoryBean多种配置方式,Spring 2.x 引入了 命名空间和基于 Annotation 的方式,使得事务规则的声明配置更为简单方便。

  • 基于 命名空间的声明式事务管理
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:aop="http://www.springframework.org/schema/aop"     xsi:schemaLocation="        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd        http://www.springframework.org/schema/aop http://www.springframework.org/schema/context/spring-aop.xsd">    <description>数据源及事务配置</description>    <!-- 配置事务管理器 -->    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        <property name="dataSource" ref="dataSource" />    </bean>    <tx:advice id="txAdvice" transaction-manager="transactionManager">        <tx:attributes>            <tx:method name="transfer" propagation="REQUIRED" />        </tx:attributes>    </tx:advice>    <!-- 配置哪些方法参与事务 -->    <aop:config>        <aop:pointcut id="allMethod" expression="execution(* service.*.*(..))"/>        <aop:advisor pointcut-ref="allMethod" advice-ref="txAdvice"/>    </aop:config></beans>
  • 基于 @Transactional 的声明式事务管理
    通过在业务处理接口、接口方法、类以及类方法上添加@Transactional注解便可实现事务配置。
@Transactional(propagation = Propagation.REQUIRED)public boolean transfer(long fromId, long toId, BigDecimal amount){    return bankDao.transfer(fromId, toId, amount);}

在配置文件中仅仅需要开启注解开关

<tx:annotation-driven transaction-manager="transactionManager" />
  • 1

这两种方式各有优点:基于 <tx>的方式,可通过切点表达式批量匹配多个方法;基于@Transactional 注解方式更为简单明了。

这里写图片描述

Spring事务管理框架包括三层:接口层、实现层和适配层。

接口层面向应用和拦截类提供简单统一的访问接口;实现层实现了Spring事务管理框架的主要逻辑,并定义了子类的抽象方法;适配层通过实现框架类将各种持久层的访问类库统一集成到Spring的事务管理框架之中。

这里写图片描述

Spring事务管理框架通过PlatformTransactionManager、TransactionDefinition、TransactionStatus接口向上层应用提供事务处理控制方法(getTransaction、commit、rollback),其中TransactionDefination接口定义事务各种属性;TransactionStatus保存事务执行状态;PlatformTransactionManager是向上层应用提供事务处理方法的接口。详见图1,这些接口在spring-tx包中定义。

图1:Spring事务处理框架接口类

TransacctionDefinition对事务的各种传播行为和隔离级别进行了定义。

这里写图片描述

这里写图片描述

这里写图片描述

Spring事务管理框架按照”1)接口层”的定义在
org.springframework.transaction.support包中提供了实现类,主要包括:
AbstractPlatformTransactionManagerDefaultTransactionDefinitionDefaultTransactionStatusSuspendedResourceHolderTransactionSynchronizationManager等。AbstractPlatformTransactionManagerDefaultTransactionDefinitionDefaultTransactionStatus分别继承实现了PlatformTransactionManagerTransactionDefinitionTransactionStatus接口。

图2:spring事务处理框架实现类

如图2中所示,AbstractPlatformTransactionManager实现了多事务处理的主要逻辑,其中私有方法suspend(Object transaction)resume(Object transaction,SuspendedResourcesHolder resourcesHolder)实现了对嵌套事务的外部事务进行调度管理,suspend方法在getTransaction调用中被触发,resume方法在commitrollback调用中被触发。

AbstractPlatformTransactionManager类中定义的一系列doXXX方法(如: doGetTransaction等)是对底层不同事务处理具体实现方法的封装,具体实现类需要实现这些方法(如:DataSourceTransactionManager)。这些方法中定义的Object transactionObject suspendedResources两个参数是关键数据,transaction相当于实现层内部定义使用的transactionStatus类,suspendedResources是实现层定义的相关资源类,它们都是Object类型,AbstractPlatformTransactionManager只对它们的值进行保存和传递,DefaultTransactionStatus中定义的两个属性对之对应。

SuspendedResourceHolder类是对嵌套事务的当前外部事务的资源暂存,对应保存在当前DefaultTransactionStatus中的suspendedResources属性。

图3: 事务处理同步管理类

图3中,TransactionSynchronizationManager是当前事务处理的上下文数据管理类,resources是当前事务所使用到的资源,如:DataSourceTransactionManager用于保存对应数据源的ConnectionHoldersynchronizations管理事务处理过程中各阶段各种资源所需要做的同步处理操作,如:ConnectionSynchronization事务执行过程中对链接的绑定与解绑,SpringLobCreatorSynchronization在事务结束时对Lob对象进行关闭。

TransactionSynchronizationManager与图2中SuspendedResourceHolder具有对应的属性,前者是保存当前事务的执行上下文;后者则是被暂停的外部事务的执行上下文,当前事务commit或rollback之后,后者的值就被恢复到TransactionSynchronizationManager

TransactionSynchronizationManager所有属性都是静态ThreadLocal变量,事务执行过程中所有方法都可以随时读取或修改当前事务的执行上下文。这样设计与事务处理的原子性保持了一致,任何时候都仅仅处于一个最小事务提交之中。

这里写图片描述

Spring在适配层继承实现AbstractPlatformTransactionManager类等,集成各种访问数据源或者消息中间件的类库,包括:

事务管理器类说明DataSourceTransactionManager位于org.springframework.jdbc.datasource包中,提供对单个javax.sql.DataSource事务管理JdoTransactionManager位于org.springframework.orm.jdo包中,提供对单个javax.jdo.PersistenceManagerFactory事务管理JpaTransactionManager位于org.springframework.orm.jpa包中,提供对单个javax.persistence.EntityManagerFactory事务支持HibernateTransactionManager位于org.springframework.orm.hibernate3包中,提供对单个org.hibernate.SessionFactory事务支持JtaTransactionManager位于org.springframework.transaction.jta包中,提供对分布式事务管理的支持,并将事务管理委托给Java EE应用服务器事务管理器OC4JjtaTransactionManager位于org.springframework.transaction.jta包中,Spring提供的对OC4J10.1.3+应用服务器事务管理器的适配器WebSphereUowTransactionManager位于org.springframework.transaction.jta包中,Spring提供的对WebSphere 6.0+应用服务器事务管理器的适配器WebLogicJtaTransactionManager位于org.springframework.transaction.jta包中,Spring提供的对WebLogic 8.1+应用服务器事务管理器的适配器

这里写图片描述

Spring事务管理框架简单易用、方便集成,它使得用户可以不用再关注事务处理的繁琐细节,而更专注于业务逻辑。另外,Spring事务管理框架本身的分层设计思想也很值得学习借鉴。