Spring源码阅读:Spring事务管理的基础

上一节了解了全局事务与局部事务以及Spring提供的两种事务模式:编程式事务与声明式事务。

不论是编程式的事务处理,还是声明式的事务处理。他们都要对局部事务和全局事务以支持,也就是说要对JDBC进行支持、ORM框架,同时也要对JTA进行支持。他们的公共部分是commit,rollback。通过这一节的了解,我相信以后配置Spring事务时,就不需要在去网上查资料了或者去查Spring的参考文档了。

因此,Spring设计了如下的事务管理框架:

从上面的类图中和容易可以看出分为三部分:PlatformTransactionManager是事务管理的核心。它可以根据TransactionDefinition获取到TransactionStatus对象,然后在事务处理过程中酌情的执行commit或者rollback。

==============================================================

接下来就来看看这三个接口是怎么描述的:

PlatformTransactionManager

/**

 * This is the central interface in Spring‘s transaction infrastructure.

 * Applications can use this directly, but it is not primarily meant as API:

 * Typically, applications will work with either TransactionTemplate or

 * declarative transaction demarcation through AOP.

 *

 * <p>For implementors, it is recommended to derive from the provided

 * {@link org.springframework.transaction.support.AbstractPlatformTransactionManager}

 * class, which pre-implements the defined propagation behavior and takes care

 * of transaction synchronization handling. Subclasses have to implement

 * template methods for specific states of the underlying transaction,

 * for example: begin, suspend, resume, commit.

 *

 * <p>The default implementations of this strategy interface are

 * {@link org.springframework.transaction.jta.JtaTransactionManager} and

 * {@link org.springframework.jdbc.datasource.DataSourceTransactionManager},

 * which can serve as an implementation guide for other transaction strategies.
*/

这个接口是Spring中事务管理的基础框架的核心。在程序中可以直接使用这个接口,但是不推荐这么做。一般来说,在应用程序中,有两种使用方式:通过编程的方式使用TransactionTemplate来或通过AOP来使用声明式事务管理。这一节并不会去了解这两种方式,而是了解他们共有的这部分基础框架。

这个接口的实现类AbstractPlatformTransactionManager 中定义了事务的传播行为,并且考虑到了事务的同步处理。AbstractPlatformTransactionManager的子类必须实现下面几个模板方法:begin,suspend,resume,commit。

TransactionDefinition

Spring是如何定义事务的呢?

public interface TransactionDefinition {

int getPropagationBehavior();

int getIsolationLevel();

int getTimeout();

boolean isReadOnly();

String getName();

}

这个接口用于定义Transaction的属性。常用的属性有:

·Propagation 传播行为:用于定义有关联的事务之间的处理机制。传播行为可以分为:Required、Supports、Mandatory、Requires_new、Not_support、Never、Nested。

其实也就是当前要执行的操作是否需要事务处理,是否在当前已存在的事务中执行,是否开启新的事务。

1Required:只要保证有事务就行。若接下来要做的操作,已经在一个事务中,就不用开启事务。如果不在事务中,就开启一个新的事务。也就是说,要保证要执行的操作在一个事务中。

2Supports:支持事务。就是说事务是可有可无的。在Supports的事务的操作时,如果操作不处于事务中,不会去创建一个新的。使用Support时的小心。

3Mandatory:强制性。就是说必须在已有的事务中,没有就抛异常。和Required明显不一样。也就是执行时,当前事务得是存在的。

4Requireds_New:这个是说事务肯定得有,并且必须是新创建的。如果已经在当前事务中,就先将当前事务挂起。

5Not_Support:不支持事务。如果当前事务存在,宁可以非事务的方式处理。

6Never:不能有事务。如果当前事务存在,抛异常。

7Nested:嵌入到当前事务中。当前事务必须存在。

·Isolation:隔离级别。前面讲过事务的几个特性中,有一个是隔离性。就是说多个共存的事务是相互隔离的。例如,当前没有提交的事务,能否被其他事务看到。

隔离级别主要处理一些三种不期望情况:

脏读:就是说一个事务T1来读取表记录,同时也有其他的事务T2来修改这些(条)记录,但是T1读的时候,其他事务T2已经对表记录改变了,但未提交,如果其他事务T2再回滚,那么这个事务T1读到的数据就是脏数据,这就是脏读。

不可重复读:就是说第一个事务T1读取表某条记录,紧接着事务T2调整了这记录并提交,事务T1第二次读取这记录。T1两次读到的数据不一致,这就是不可重复读。针对单条记录。

虚读:就是说第一个事务T1读取表某些(where条件下的多条记录)记录,紧接着事务T2调整了这记录并提交,事务T1第二次读取这记录。T1两次读到的数据不一致,这就是不可重复读。针对多条记录。

Spring中提供的隔离级别的支持:

1)Default

2)Read_Uncommited,当前事务没有提交时,其他事务可以读取数据。在这种隔离级别是,就会有可能发生脏读、不重复读、虚读 等情况。

3)Read_Commited:读到的是其他事务提交后的数据,避免了脏读的发生。还会出现不可重复读和虚读。

4)Repeatable_Read:可重复读。这种情况下,避免了脏读、不可重复读的情况。

5)Serializable:避免三种情况。

·TimeOut:事务运行超时(超过指定时限)后自动回滚。-1代表没有时限。

·ReadOnly_Status。只读事务。

Spring框架就是通过TransactionDefinition来定义事务的。

TransactionStatus

public interface TransactionStatus extends SavepointManager {
    boolean isNewTransaction();
    boolean hasSavepoint();
    void setRollbackOnly();
    boolean isRollbackOnly();
    void flush();
    boolean isCompleted();
}

TransactionStatus,用于从代码上控制事务,提供了事务状态查询功能。

PlatformTransactionManager如何使用??

在Spring中,不论使用哪种模式(编程式、声明式)的事务管理,正确的定义PlatformTransactionManager的实现类,是很重要的。通常是通过Spring的DI定义TransactionManager的。这点对于两种模式的事务管理都是可用的。

根据不同的情况,可以定义各种事务管理:

譬如说,可以定义

同时还可以集成Hibernate等ORM框架,图我就不贴了。

Spring源码阅读:Spring事务管理的基础

时间: 2024-08-09 10:42:44

Spring源码阅读:Spring事务管理的基础的相关文章

Spring源码阅读:Spring声明式事务处理和编程式事务处理的设计与实现

之前的学习,了解了Spring事务管理的基础框架(查看).Spring在此基础上又提到了声明式事务管理和编程式事务管理.这里就来看看Spring是如何实现的. Spring声明式事务与EJB事务管理对比 Spring的声明式管理,类似于EJB的CMT,但又有不同.他们的不同之处有: 1)EJB的CMT是与JTA结合使用,而Spring框架的声明式事务管理可以在任何环境下工作.既可以使用全局事务管理,如JTA,也可以使用局部事务管理如JDBCJPA.Hibernate.JDO等. 2)可以在任何类

Spring源码阅读系列总结

最近一段时间,粗略的查看了一下Spring源码,对Spring的两大核心和Spring的组件有了更深入的了解.同时在学习Spring源码时,得了解一些设计模式,不然阅读源码还是有一定难度的,所以一些重要的设计模式简单的做了阐述.同时还会简单的加入一些GOF中提到的设计原则.Spring的源码阅读系列,也暂告一段落.下面是就带你走进Spring世界: Spring系列的引子 1)Spring WebApplicationContext初始化与消亡 这一节帮我们了解Spring是如何初始化WebAp

Spring源码阅读:Spring MVC 如何处理HTTP请求

Spring MVC 对HTTP请求的处理流程 通过之前的源码阅读,知道了ApplicationContext初始的过程,也知道了Spring MVC环境的初始化过程,今天就来了解一下SpringMVC是如何处理HTTP请求的. HTTP请求根据请求方式可以分为GET.POST.PUT.DELETE.OPTIONS.TRACE,最常用的还是GET和POST. Spring对于这几种HTTP请求的处理都是使用了processRequest(req,rep); @Override protected

Spring源码阅读:IOC容器的设计与实现(二)——ApplicationContext

上一主题中,了解了IOC容器的基本概念,以及BeanFactory的设计与实现方式,这里就来了解一下ApplicationContext方式的实现. ApplicationContext 在Spring的参考文档中,为啥要推荐使用ApplicationContext?它能给我们的应用带来什么好处呢?作为BeanFactory的实现之一,它又是如何设计的?在SpringMVC中使用的WebApplictionContext\XmlApplicationContext与之有何关联? Applicat

Spring源码阅读:Spring如何支持各种ORM框架

为了让开发程序更容易,到现在为止,已经有很多ORM框架了,例如:JPA,JDO,Hibernate,Mybatis(之前版本是IBatis)等等.也正因为已经有这么多优秀的ORM框架,Spring团队并没有自己开发一套ORM框架,而是对这些框架都进行了支持,让这些框架在Spring环境下可以得到完全的应用. 通常,在Spring环境下使用这些ORM框架时,都会通过一个Template来使用.Spring对这些框架的集成是这样的: 例如Hibernate,在使用Hibernate时(没有在Spri

Spring源码阅读:Spring AOP设计与实现(一):动态代理

在Spring的有两个核心:IOC与AOP,AOP又是基于动态代理模式实现的.所以要了解SpringAOP是如何设计的之前,还是先了解一下Java中的动态代理比较好. 认识代理模式 代理模式是这么描述的: 代理模式是为其他对象提供一种代理以控制对这个对象的访问 代理对象的功能: 通过创建一个代理对象,用这个代理对象去代理真实的对象,客户端得到这个代理对象后,对客户端并没有什么影响,就跟真实的对象一样(因为代理对象和真是对象实现了同一接口). 下面看看代理模式的类图: 解说: RealSubjec

Spring源码阅读:Spring WebApplicationContext初始化与消亡

使用SpringMVC时,需要不论是使用注解配置,还是使用XML配置Bean,他们都会在Web服务器启动后就初始化.根据J2ee的知识可以知道,肯定是使用了ServletContextListener才完成的这个功能.那Spring又是如何实现的呢?还有我们在Web.xml配置的那些applicationContext.xml相关的XML文件的位置(配置方式多样),又是如何读取到相应的文件的呢,读取到这些文件后,是如何初始化类的呢?我们能不能自定义初始化过程或者自定义WebApplication

Spring源码阅读:Spring MVC 初始化

通过之前的源码学习,了解了Spring的两个核心IOC和AOP.也了解到系统初始化时,就已经将所有applicationContext.xml中的bean Definintion加载并初始化了. 如果使用了SpringMVC框架,MVC框架指定的namespace-servlet.xml也已经被初始化了. 使用过SpringMVC,都知道需要在web.xml配置配置DispatcherServlet,它是处理请求的入口.Servlet是单例的,系统指挥在第一次处理用户请求时初始化Servlet对

Spring源码阅读:Spring JDBC 组件的设计与实现

昨天回忆了我在学习JDBC时自己设计的JDBCTemplate(写在上一篇博客中),在使用Spring过程中,有时会用到Spring给我们提供的JdbcTemplate,这里看看Spring是如何实现这个组件的. 在使用Spring JDBC是你要做的工作很少: 从上面的图上可以看出来,使用Spring JDBC,你只需要做四个工作: 1)定义连接参数:也就是定义url,driver,user,password这个几个参数,一般我们会用一个jdbc.properties文件来配置. 2)指定要执