Spring框架之事务源码完全解析
事务的定义及特性:
事务是并发控制的单元,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是一个不可分割的工作单位。通过事务将逻辑相关的一组操作绑定在一起,以便服务器保持数据的完整性。事务通常是以begin transaction开始,以commit或rollback结束。commint表示提交,即提交事务的所有操作。具体地说就是将事务中所有对数据的更新写回到磁盘上的物理数据库中去,事务正常结束。rollback表示回滚,即在事务运行的过程中发生了某种故障,事务不能继续进行,系统将事务中对数据库的所有已完成的操作全部撤消,滚回到事务开始的状态。
事务的特性:
原子性(Atomic)对数据的修改要么全部执行,要么全部不执行。
一致性(Consistent)在事务执行前后,数据状态保持一致性。
隔离性(Isolated)一个事务的处理不能影响另一个事务的处理。
持续性(Durable)事务处理结束,其效果在数据库中持久化。
Java事务的三种类型
JDBC事务、JTA(Java Transaction API)事务、容器事务。
(1)JDBC事务
JDBC 事务是用 Connection 对象控制的。JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。 java.sql.Connection 提供了以下控制事务的方法:
public void setAutoCommit(boolean)
public boolean getAutoCommit()
public void commit()
public void rollback()
使用 JDBC 事务界定时,您可以将多个 SQL 语句结合到一个事务中。JDBC 事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库。
(2)JTA(Java Transaction API)事务
JTA是一种高层的,与实现无关的,与协议无关的API,应用程序和应用服务器可以使用JTA来访问事务。
JTA允许应用程序执行分布式事务处理—在两个或多个网络计算机资源上访问并且更新数据,这些数据可以分布在多个数据库上。JDBC驱动程序的JTA支持极大地增强了数据访问能力。
如果计划用 JTA 界定事务,那么就需要有一个实现 javax.sql.XADataSource 、 javax.sql.XAConnection 和 javax.sql.XAResource 接口的 JDBC 驱动程序。一个实现了这些接口的驱动程序将可以参与 JTA 事务。一个 XADataSource 对象就是一个 XAConnection 对象的工厂。 XAConnection是参与 JTA 事务的 JDBC 连接。
您将需要用应用服务器的管理工具设置 XADataSource。从应用服务器和 JDBC 驱动程序的文档中可以了解到相关的指导。
J2EE应用程序用 JNDI 查询数据源。一旦应用程序找到了数据源对象,它就调用 javax.sql.DataSource.getConnection()以获得到数据库的连接。
XA 连接与非 XA 连接不同。XA 连接参与了 JTA 事务。这意味着 XA 连接不支持 JDBC 的自动提交功能。同时,应用程序一定不要对 XA 连接调用 java.sql.Connection.commit()或者 java.sql.Connection.rollback()。相反,应用程序应该使用 UserTransaction.begin()、UserTransaction.commit() 和 serTransaction.rollback()。.
(3)容器事务
容器事务主要是J2EE应用服务器提供的,容器事务大多是基于JTA完成,这是一个基于JNDI的,相当复杂的API实现。相对编码实现JTA事务管理, 我们可以通过EJB容器提供的容器事务管理机制(CMT)完成同一个功能,这项功能由J2EE应用服务器提供。这使得我们可以简单的指定将哪个方法加入事 务,一旦指定,容器将负责事务管理任务。通过这种方式我们可以将事务代码排除在逻辑编码之外,同时将所有困难交给J2EE容器去解决。使用EJB CMT的另外一个好处就是程序员无需关心JTA API的编码,不过,理论上我们必须使用EJB。
(4)三种Java事务差异
JDBC事务控制的局限性在一个数据库连接内,但是其使用简单。
JTA事务的功能强大,事务可以跨越多个数据库或多个DAO,使用也比较复杂。
容器事务,主要指的是J2EE应用服务器提供的事务管理,局限于EJB应用使用。
(5)应用场景
Java事务控制是构建J2EE应用不可缺少的一部分,合理选择应用何种事务对整个应用系统来说至关重要。一般说来,在单个JDBC 连接的情况下可以选择JDBC事务,在跨多个连接或者数据库情况下,需要选择使用JTA事务,如果用到了EJB,则可以考虑使用EJB容器事务。
下面基于的Spring版本为5.2.4.BUILD-SNAPSHOT源码,对Spring事务tx模块中包含的类和接口进行介绍。
一、dao
Spring事务中的dao模块定义了数据库层的各种异常,主要是dao的支持和异常的转译。在这里简要介绍Dao设计模式:
Dao设计模式(Data Access Object),称为数据访问对象。它是对于数据库操作的一种设计方式,把Dao设计为一个通用接口,提供对数据库进行增、删、改、查的一系列操作数据库的抽象方法。通俗来讲,就是将数据库操作都封装起来。
面向对象编程的核心就是类、对象。数据库中每一张Table可以看作一个Class,而列就可以看作类中的一些属性。这是面向对象的基本思想,通过这种思想我们需要提供的Class就相当于Table的数量。而每次对数据库的操作时,根据查询的Table不同,就会得到不同的Class。
又因为每个Class中操作增、删、改、查的方法都大相近庭,这就造成的代码的冗余、所以就出现Dao的设计思想。利用Dao接口提供的抽象方法对数据库进行操作就大大的降低代码重复,间接地可以提高程序的效率、性能等。
Dao模式的优势就在于它实现了两次隔离。
(1)隔离了数据访问代码和业务逻辑代码。业务逻辑代码直接调用Dao方法即可,完全感觉不到数据库表的存在。分工明确,数据访问层代码变化不影响业务逻辑代码,这符合单一职能原则,降低了耦合性,提高了可复用性。
(2)隔离了不同数据库实现。采用面向接口编程,如果底层数据库变化,如由 MySQL 变成 Oracle 只要增加Dao接口的新实现类即可,原有 MySQ 实现不用修改。这符合 "开-闭" 原则。该原则降低了代码的耦合性,提高了代码扩展性和系统的可移植性。
一个典型的Dao模式主要由以下几部分组成:
(1)Dao接口: 把对数据库的所有操作定义成抽象方法,可以提供多种实现。
(2)Dao实现类: 针对不同数据库给出Dao接口定义方法的具体实现。
(3)实体类:用于存放与传输对象数据。
(4)数据库连接和关闭工具类: 避免了数据库连接和关闭代码的重复使用,方便修改。
01 dao/
1.1 CannotAcquireLockException:执行一个更新获取相应锁失败时抛出的异常,比如一个"select for update"语句。
1.2 CannotSerializeTransactionException:执行一个序列化模式下的事务失败抛出的异常。
1.3 CleanupFailureDataAccessException:在一个数据访问操作正常结束后我们无法进行清理抛出的异常。比如,一个JDBC连接在成功被使用后无法关闭。
1.4 ConcurrencyFailureException:并发失败时抛出的异常。该异常类需要被子类继承以指示失败的类型:乐观锁、未能成功获取锁等。
1.5 DataAccessException:数据访问异常类的一个处于根位置的基类。
1.6 DataAccessResourceFailureException:资源完全失效时抛出的数据访问异常。比如,我们使用JDBC无法连接到一个数据库中。
1.7 DataIntegrityViolationException:当尝试插入或者更新数据时违反了完整性约束时抛出的异常。
1.8 DataRetrievalFailureException:检索数据失败时抛出的异常,比如,通过一个已知标识符查找指定的数据。该异常类会被对象关系映射工具或者DAO实现类抛出。
1.9 DeadlockLoserDataAccessException:当前进程发生死锁,它的事务需要回滚时抛出的一般异常。
1.10 DuplicateKeyException:当尝试插入或者更新数据时违反了主键或者唯一性约束抛出的异常。
1.11 EmptyResultDataAccessException:当期望返回的结果至少包含一行数据(或者元素),但实际只有0个时抛出的异常。
1.12 IncorrectResultSizeDataAccessException:当返回的结果大小和期望的不一致时抛出的异常,比如,期望得到1行数据但是返回的0或者多于1行的数据。
1.13 IncorrectUpdateSemanticsDataAccessException:当在执行更新操作时发生了一些计划外的事情,但是事务并没有要回滚时抛出的数据读取异常。比如,当我们想要更新数据库管理系统中的1行数据时,但是却实际更新了3行。
1.14 InvalidDataAccessApiUsageException:对API错误使用抛出的异常,例如未能 “编译”需要在执行前编译的查询对象。
1.15 InvalidDataAccessResourceUsageException:当我们不正确使用一个数据读取资源时抛出异常。比如,在使用关系数据库管理系统指定了错误的SQl语句。
1.16 NonTransientDataAccessException:一种非暂态的数据访问异常,因为同一操作的重试仍然会失败还会引发该异常,除非引发异常的原因排除。
1.17 NonTransientDataAccessResourceException:资源完全失效抛出的数据访问异常,而且这种失效是永久的。
1.18 OptimisticLockingFailureException:乐观锁冲突抛出的异常。对象关系映射工具或者个性化的DAO实现类会抛出该异常。乐观锁失效通常不是由数据库自身检测出来。
1.19 PermissionDeniedDataAccessException:当一个潜在的资源被拒绝访问一个指定的元素,比如一个指定的数据库表时抛出的异常。
1.20 PessimisticLockingFailureException:悲观锁冲突引发的异常。当发生这种数据库错误的时候,由Spring的SQLException转换机制抛出。
1.21 QueryTimeoutException:查询超时抛出的异常。根据使用的数据库API可能会有不同的原因引发该异常,最有可能的就是一个执行中的查询操作完成前被数据库中断或者中止了。
1.22 RecoverableDataAccessException:如果应用执行一些恢复步骤、重试整个事务或者如果是分布式事务,事务分开,先前一个失败的操作可能可以成功的抛出的数据访问异常。
1.23 TransientDataAccessException:表示一些暂态的数据访问异常,当操作在无干扰的情况下重试,先前失败的操作很可能会成功。
1.24 TransientDataAccessResourceException:当资源暂时性失效、操作还可以重试时抛出的数据访问异常。
1.25 TypeMismatchDataAccessException:Java类型和数据库类别不匹配时抛出的异常。比如,尝试将错误类型的对象设置到一个关系数据库管理系统的列上。
1.26 UncategorizedDataAccessException:无法归类的异常,比如,JDBC发生了一个SQLException,但是我们无法将其精确定位到更具体的异常。
02 dao/annotation
2.1 PersistenceExceptionTranslationAdvisor:是一个spring aop的异常转译类,它应用到respository层或者dao层。它基于给定的PersistenceExceptionTranslator来将本地持久化异常转换为spring的DataAccessException族。
2.2 PersistenceExceptionTranslationPostProcessor:自动将标示为@repository的bean的持久化异常进行转译。它增加一个PersistenceExceptionTranslationAdvisor来代理相应的已经存在的aop代理或者实现了目标接口的新产生的代理。它将本地资源异常转换为spring的DataAccessException及其子类上。
03 dao/support
3.1 DaoSupport:DAOs的通用基类,定义了DAO初始化的模板方法。会被Spring的DAO支持类所继承,比如JdbcDaoSupport, JdoDaoSupport等等。
3.2 DataAccessUtils:DAO实现类的各种实用方法。适用于任何数据访问技术。提供的方法主要用于从给定的集合中返回结果对象,如果找到0个或者多个则抛出相应的异常。
3.3 PersistenceExceptionTranslator:spring集成其它数据获取技术(如jpa、toplink、jdo、hibernate等)抛出运行时异常的接口。
3.4 ChainedPersistenceExceptionTranslator:PersistenceExceptionTranslator接口的实现类,支持链技术,允许按顺序添加PersistenceExceptionTranslator实例。
3.5 PersistenceExceptionTranslationInterceptor:一个aop 方法拦截器(MethodInterceptor)。提供基于PersistenceExceptionTranslator的异常转换,它是PersistenceExceptionTranslator的代理,将运行时抛出的异常转换为spring 的DataAccessException族。
二、jca
JCA (J2EE 连接器架构,Java Connector Architecture)是对J2EE标准集的重要补充。因为它注重的是将Java程序连接到非Java程序和软件包中间件的开发。连接器特指基于Java连接器架构的源适配器,其在J2EE 1.3规范中被定义。JCA连接器同时提供了一个重要的能力,即它使J2EE应用服务器能够集成任何使用JCA适配器的企业信息系统(EIS),大大简化了异构系统的集成。有了JCA,企业只要购买一个基于JCA规范的适配器,就可以将企业应用部署到J2EE服务器上,这样不用编写任何代码就可以实现与J2EE应用服务器的集成。JCA还提供了一个应用服务器和EIS连接的标准Java解决方案。
JCA的目标在于企业应用程序集成方面,它提供的标准化体系结构让J2EE组件能够对异构EIS进行“即插即用”的访问,其中包括ERP、事务处理、老式数据库系统等。
JCA定义了一套标准的接口SPI,用于让连接器把兼容的应用程序服务器无缝的整合起来。同时,定义的另一套标准接口CCI允许客户(或者应用程序服务器的应用程序主机)用一种统一的方法使用连接器。这样,连接器对于跨应用程序服务器就是可移植的,而客户程序成为很轻便的连接器。
(1)SPI(Service provider interfaces)是连接器提供者(connector provider)必须实现的接口。 这些接口组成了一个能被部署在J2EE应用服务器上的资源适配器(resource adapter)。 在这种情况下,由服务器来管理连接池(connection pooling)、事务和安全(托管模式(managed mode))。 应用服务器还负责管理客户端应用程序之外所拥有的配置。连接器(connector)同样能在脱离应用服务器的情况下使用;在这种情况下,应用程序必须直接对它进行配置(非托管模式(non-managed mode))。
(2)CCI (Common Client Interface)是应用程序用来与连接器交互并与EIS通信的接口。同样还为本地事务划界提供了API。
Spring对CCI的支持,目的是为了提供以典型的Spring方式来访问CCI连接器的类,并有效地使用Spring的通用资源和事务管理工具。
注意: 连接器的客户端不必总是使用CCI。 某些连接器暴露它们自己的API,只提供JCA资源适配器(resource adapter) 以使用J2EE容器的某些系统契约(system contracts)(连接池(connection pooling),全局事务(global transactions),安全(security))。 Spring并没有为这类连接器特有(connector-specific)的API提供特殊的支持。
01 jca/cci/
1.1 CannotCreateRecordException:因为连接器内部原因无法创建一个CCI Record抛出的异常。
1.2 CannotGetCciConnectionException:当我们使用CCI (Common Client Interface)无法连接到一个EIS(企业信息系统)抛出的致命异常。
1.3 CciOperationNotSupportedException:当连接器不支持一个指定的CCI操作时抛出的异常。
1.4 InvalidResultSetAccessException:以无效的方式访问一个结果集时抛出的异常。比如指定一个无效的结果集的列索引或者名字时发生。
1.5 RecordTypeNotSupportedException:当连接器不支持CCI Record类型,导致创建一个CCI Record失败时抛出的异常。
jca/cci/connection
1.6 CciLocalTransactionManager :继承自PlatformTransactionManager,为一个CCI 连接工厂管理本地事务。将来自指定ConnectionFactory的CCI 连接绑定到线程中。
应用代码需要通过ConnectionFactoryUtils类的getConnection(ConnectionFactory)方法来获取CCI连接,而不是用标准的Java EE-style ConnectionFactory类的getConnection()方法。
1.7 ConnectionFactoryUtils:帮助类,提供了从一个javax.resource.cci.ConnectionFactory中获取CCI 连接的静态方法。为Spring管理事务连接提供了专门的支持,比如通过CciLocalTransactionManager或JtaTransactionManager进行管理。
该类会被CciTemplate、Spring的CCI操作对象和CciLocalTransactionManager内部使用,也可以直接在应用代码中使用。
1.8 ConnectionHolder:封装了一个CCI 连接的资源句柄。CciLocalTransactionManager为一个给定的ConnectionFactory绑定该类的实例到线程中。
1.9 ConnectionSpecConnectionFactoryAdapter:一个目标CCI ConnectionFactory适配器,将给定的ConnectionSpec应用到每一个标准的getConnection()方法中,也就是说,在目标上调用getConnection(ConnectionSpec)方法。其他所有的方法简单的委托给目标ConnectionFactory相应的方法。
1.10 DelegatingConnectionFactory:CCI ConnectionFactory接口的实现类,将所有的调用委托给给定的目标ConnectionFactory。
该类最好被子类继承,子类可以覆盖这些方法(比如getConnection()),而不是简单的委托给目标ConnectionFactory。
1.11 NotSupportedRecordFactory:CCI RecordFactory接口的实现类,总是抛出NotSupportedException异常。
作为RecordFactory参数的占位符使用(比如,由RecordCreator回调定义),尤其是当连接器的ConnectionFactory.getRecordFactory()实现抛出NotSupportedException异常,而不是从 RecordFactory的方法中抛出异常。
1.12 SingleConnectionFactory:一个CCI ConnectionFactory适配器,对于所有的getConnection调用返回相同的连接,忽略对Connection.close()的调用。
用于测试或者单机的环境中,对不同的CciTemplate调用,使用相同的连接,没有池连接工厂,同时也跨越任意数量的事务。
1.13 TransactionAwareConnectionFactoryProxy:代理一个目标CCI ConnectionFactory,增加了对Spring管理事务的感知。同Java EE server提供的事务JNDI ConnectionFactory相似。
jca/cci/core/
1.14 CciOperations:指定在企业信息系统(EIS)上的一套基本的操作的接口。被CciTemplate实现。不常用,但是可以用来增强测试,因为它可以方便的进行mocked or stubbed。
Mock:我们可以在不实现具体对象的情况下,即在没有某个类的实例的情况下对该对象的行为进行模拟。这一特征对于面向接口的编程非常有用。因为接口的调用者可以在没有接口的具体实现的情况下使用接口,也就是说调用者可以先于接口的实现者行动。
它的主要工作是模拟出一个被模拟对象的实例,其中包括模拟对该实例的调用行为(比如访问属性、调用方法之类)、模拟方法或属性访问的返回值、模拟方法和索引的参数传递等等,可以说基本上对于一个对象实例的使用它都可以模拟出来。这样一来,我们就可以好像真的有一个我们需要的实例存在一样,正常地使用它,来完成对调用者代码的开发和测试。
mock使用easymock等包,在程序代码中向被测试代码注入“依赖部分”,通过代码可编程的方式模拟出函数调用返回的结果。mock关注行为验证。细粒度的测试,即代码的逻辑,多数情况下用于单元测试。
stub:是真实对象的一个模拟,比如调用者需要一个值,那就让stub输出一个值,如果调用者需要传递一个值给stub,那就在stub中定义一个方法接受该参数。
但是这与mock的对象存在本质的区别:stub虽然说也是模拟,但其本质上对真是对象的一个简单实现,而无论它有多简单它都是一种实现,它是真实存在的,它里面包含了我们定义的操作代码;反观mock的对象,它根本是不存在的,哪怕一句的简单的不能再简单的代码都不存在。
stub自己写代码代替“依赖部分”。它本身就是“依赖部分”的一个简化实现。stub关注状态验证。粗粒度的测试,在某个依赖系统不存在或者还没实现或者难以测试的情况下使用,例如访问文件系统,数据库连接,远程协议等。
1.15 CciTemplate:CCI core包和核心类。它简化了对CCI的使用,帮助避免一些常见的错误。它执行核心CCI工作流,这样应用代码只需要提供参数给CCI然后获取结果。该类执行企业信息系统(EIS)的查询和更新操作,捕获ResourceExceptions异常同时将这些异常转换成在org.springframework.dao包中定义的通用异常类。
1.16 ConnectionCallback:通用的回调接口,用于操作一个CCI连接的代码。允许使用任意类型和数量的交互,在单个连接上执行任意数量的操作。
1.17 InteractionCallback:通用的回调接口,用于操作一个CCI交互的代码。允许在单个交互上执行任意数量的操作,比如单个的execute调用或者使用不同参数多次execute调用。
1.18 RecordCreator:回调接口,用于创建一个CCI Record实例,常常基于passed-in CCI RecordFactory。
1.19 RecordExtractor:回调接口,用于从一个CCI Record实例中获取一个结果对象。
jca/cci/core/support
1.20 CciDaoSupport:基于CCI的数据读取对象的父类。需要设置一个ConnectionFactory,提供一个CciTemplate。
1.21 CommAreaRecord:CCI Record接口的实现类,用于COMMAREA,持有一个字节数组。
jca/cci/object
1.22 EisOperation:使用CCI API的EIS操作对象的基类。封装了一个CCI ConnectionFactory 和一个 CCI InteractionSpec。
1.23 MappingCommAreaOperation:EIS操作对象用于访问COMMAREA records。
1.24 MappingRecordOperation:EIS操作对象,该抽象类的子类必须实现抽象函数createInputRecord(RecordFactory, Object):从一个对象创建一个input Record。extractOutputData(Record):转换一个output Record到一个对象。
1.25 SimpleRecordOperation:EIS操作对象,接受一个passed-in CCI input Record,返回一个相应的CCI output Record。
02 jca/context
2.1 BootstrapContextAware:需要通知BootStrapContext的实现类。
2.2 BootstrapContextAwareProcessor:传递BootstrapContext到实现了BootStrapContextAware接口的spring bean。它在内部bean factory中自动注册。
2.3 ResourceAdapterApplicationContext:一个jca ResourceAdapter的applicationContext实现,需要于jca的bootstrapContext一同初始化,最后传递到实现了BootstrapContextAware的spring 受管理bean。
2.4 SpringContextResourceAdapter:JCA 1.7 ResourceAdapter接口实现类,加载了一个Spring ApplicationContext容器,启动和停止Spring托管的bean作为ResourceAdapter生命周期的一部分。
03 jca/endpoint
3.1 AbstractMessageEndpointFactory:实现了jca 1.5、1.6、1.7版本的javax.resource.spi.endpoint.MessageEndpointFactory接口,它提供了事务管理能力。
3.2 GenericMessageEndpointFactory:实现了抽象方法,对任意类型的消息监听对象(javax.jms.MessageListener)或者javax.resource.cci.MessageListener对象提供了事务管理的能力。
3.3 GenericMessageEndpointManager:使用Spring application context对JCA 1.7 消息端点进行管理的通用的bean。激活和停止这个端点作为application context容器生命周期的一部分。
04 jca/support
4.1 LocalConnectionFactoryBean:创建一个本地JCA连接工厂。
4.2 ResourceAdapterFactoryBean:使用BootStrapContext启动一个jca 1.5指定的ResouceAdapter。
4.3 SimpleBootstrapContext:BootstrapContext提供一种机制,这种机制将一个Bootstrap的上下文传递到一个资源适配器实例。
05 jca/work
5.1 DelegatingWork:简单的任务适配器,委托给一个给定的Runnable。
5.2 SimpleTaskWorkManager:JCA 1.7 javax.resource.spi.work.WorkManager接口的简单实现,委托给一个Spring TaskExecutor。提供了简单的任务执行,但是不支持一个JCA ExecutionContext(比如,不支持导入的事务)。
5.3 WorkManagerTaskExecutor:TaskExecutor接口实现类,代表一个JCA 1.7 WorkManager,实现了WorkManager接口。
三、transaction
01 transaction/
1.1 PlatformTransactionManager:事务管理接口,完成对事务的管理和操作,比如开启事务,提交和回滚事务。通过实现此接口,完成对已经创建的事务进行操作。该接口中提供了三个事务操作方法,具体如下。
TransactionStatus getTransaction(TransactionDefinition definition):用于获取事务状态信息。
void commit(TransactionStatus status):用于提交事务。
void rollback(TransactionStatus status):用于回滚事务。
事务三大接口:
PlatformTransactionManager 事务管理器。
TransactionDefinition 事务的一些基础信息,如超时时间、隔离级别、传播属性等。
TransactionStatus 事务的一些状态信息,如是否一个新的事务、是否已被标记为回滚。
1.2 TransactionDefinition:事务定义信息(配置信息来自xml配置文件和注解)。包括事务的隔离级别,事务的传播特性,事务超时时间,事务只读特性。它提供了事务相关信息获取的方法,其中包括五个操作:
String getName():获取事务对象名称。
int getIsolationLevel():获取事务的隔离级别。
int getPropagationBehavior():获取事务的传播行为。
int getTimeout():获取事务的超时时间。
boolean isReadOnly():获取事务是否只读。
事务隔离级别:
事务四大特性 : ACID 原子性、一致性、隔离性、持久性。隔离性引发并发问题:脏读、不可重复读、虚读。脏读:一个事务读取另一个事务未提交数据。不可重复读:一个事务读取另一个事务已经提交 update 数据。虚读:一个事务读取另一个事务已经提交 insert 数据。事务隔离级别为了解决事务隔离性引发问题,定义了5种隔离级别:
ISOLATION_DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应。
ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。
ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。
事务的传播行为
传播行为解决问题:一个业务层事务调用另一个业务层事务,事务之间关系如何处理。事务的传播行为在jdbc规范中是没有定义的,jdbc规范只定义了事务的隔离级别。为什么要有事务的传播行为,就是为了方便开发实际开发中的问题:业务层方法之间的互相调用。
例如:删除客户的同时,也要删除与客户相关联的订单。这时就会在CustomerService的deleteCustomer方法中调用OrderSerivce中的deleteOrder方法。如果订单删除失败了,那么就不应该删除客户,所以这两个操作必须放到同一个事务中。另一种情况:订单删除失败了,仍然要把客户删除,这两个操作也需要事务。
传播行为解决的问题是:一个业务层的事务,调用另一个业务层事务,事务之间的关系如何处理。
在Spring中定义了七中事务传播行为:
(1) PROPAGATION_REQUIRED:支持当前事务,如果不存在就新建一个。
删除客户时删除订单,处于同一个事务,如果删除订单失败,删除客户也要回滚。
(2) PROPAGATION_SUPPORTS :支持当前事务,如果不存在,就不使用事务。
删除客户时删除订单,如果删除客户时没有开启事务,那么删除订单也不使用事务。
(3)PROPAGATION_MANDATORY:支持当前事务,如果不存在,抛出异常。
删除客户时删除订单,如果在删除订单时没开事务,则抛出异常。
(4)PROPAGATION_REQUIRES_NEW:如果有事务存在,挂起当前事务,创建一个新的事务。
生成订单,发送通知邮件,通知邮件会创建一个新的事务,如果邮件失败,不影响订单生成事务。
(5)PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果有事务存在,挂起当前事务。
(6)PROPAGATION_NEVER:以非事务方式运行,如果有事务存在,抛出异常。
(7)PROPAGATION_NESTED 如果当前事务存在,则嵌套事务执行。依赖于 JDBC3.0 提供 SavePoint 技术。
删除客户删除订单, 在删除客户后,设置SavePoint,执行删除订单,删除订单和删除客户在同一个事务,删除订单失败,事务回滚 SavePoint,由用户控制是事务提交还是回滚。
1.3 TransactionStatus :事务的一些状态信息,如是否是一个新的事务、是否已被标记为回滚。
isNewTransaction():返回当前事务状态是否是新事务;
hasSavepoint():返回当前事务是否有保存点;
setRollbackOnly():设置当前事务应该回滚;
isRollbackOnly(():返回当前事务是否应该回滚;
flush():用于刷新底层会话中的修改到数据库,一般用于刷新如Hibernate/JPA的会话,可能对如JDBC类型的事务无任何影响;
isCompleted():当前事务否已经完成。
1.4 CannotCreateTransactionException:使用一个事务API比如JTA(即Java Transaction API),创建不了一个事务时抛出的异常。
1.5 HeuristicCompletionException:事务协调器试探式的决策导致事务失败抛出的异常。
1.6 IllegalTransactionStateException:根据应用的事务传播行为,当事务的存在或不存在等于非法状态时引发异常。
1.7 InvalidIsolationLevelException:当指定了一个非法的隔离级别时抛出的异常,比如,一个事务管理器不支持的隔离级别。
在标准SQL规范中定义了4个事务隔离级别,不同隔离级别对事务处理不同:
(1) 未授权读取 Read Uncommitted:也称未提交读。防止更新丢失(对应一级锁),如果一个事务已经开始写数据则另外一个数据则不允许同时进行写操作但允许其他事务读此行数据。该隔离级别可以通过“排他写锁”实现。事务隔离的最低级别,仅可保证不读取物理损坏的数据。与READ COMMITTED 隔离级相反,它允许读取已经被其它用户修改但尚未提交确定的。
(2)授权读取 Read Committed:也称提交读。“未授权读取”之上防止脏读取(对应二级锁)。这可以通过“瞬间共享读锁”和“排他写锁”实现,读取数据的事务允许其他事务继续访问该行数据,但是未提交写事务将会禁止其他事务访问该行。SQL Server 默认的级别。在此隔离级下,SELECT 命令不会返回尚未提交(Committed) 的数据,也不能返回脏数据。
(3)可重复读取 Repeatable Read:“授权读取”之上防止不可重复读取(对应三级锁)。但是有时可能出现幻影数据,这可以通过“共享读锁”和“排他写锁”实现,读取数据事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。在此隔离级下,用SELECT 命令读取的数据在整个命令执行过程中不会被更改。此选项会影响系统的效能,非必要情况最好不用此隔离级。三级封锁协议并不能阻止幻读,修改的不能再被读取,但是新增(删除)的记录数可以统计。
(4)串行 Serializable:也称可串行读(对应两段锁)。提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。如果仅仅通过 “行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作事务访问到。事务隔离的最高级别,事务之间完全隔离。如果事务在可串行读隔离级别上运行,则可以保证任何并发重叠事务均是串行的。
1.8 InvalidTimeoutException:指定一个非法的timeout时限抛出的异常,也就是说指定的时限超出了范围或者事务管理器不支持时限。
1.9 NestedTransactionNotSupportedException:试图使用嵌套式事务,但是底层后端不支持嵌套式事务抛出的异常。
1.10 NoTransactionException:当一个操作依赖于一个现有的事务(比如设置回滚的状态),但是不存在这个现有的事务时抛出的异常。该异常表示非法使用事务API的情况。
1.11 ReactiveTransaction:表示一个还在发展中的反应式事务。现在是拓展自TransactionExecutio的标记接口,在将来的版本中可能会进一步包含方法。
事务代码能使用该类获取状态信息,以编程方式请求一个回滚(而不是抛出一个异常而引发一个完全的回滚)。
1.12 ReactiveTransactionManager:在Spring响应式事务架构中这个一个核心接口。应用可以直接使用该接口,但它并不是主要做API使用:通常,应用通过AOP使用事务操作或者声明式事务划分。
1.13 SavepointManager:以通用的方式管理事务保存点(savepoint)。会被TransactionStatus继承,为一个指定的事务暴露保存点管理器。
1.14 StaticTransactionDefinition:一个静态的、不可更改的transaction definition。
1.15 TransactionException:所有事务异常类的父类。
1.16 TransactionExecution:用来表示事务的当前状态,作为TransactionStatus和ReactiveTransaction的父接口。
1.17 TransactionManager:Spring事务管理器实现类的标记接口,传统的或者反应式的。
Marker Interface标记接口有时也叫标签接口(Tag interface),即接口不包含任何方法。
标记接口是计算机科学中的一种设计思路。编程语言本身不支持为类维护元数据。而标记接口则弥补了这个功能上的缺失:一个类实现某个没有任何方法的标记接口,实际上标记接口从某种意义上说就成为了这个类的元数据之一。运行时,通过编程语言的反射机制,我们就可以在代码里拿到这种元数据。
以Serializable接口为例。一个类实现了这个接口,说明它可以被序列化。因此,我们实际上通过Serializable这个接口,给该类标记了“可被序列化”的元数据,打上了“可被序列化”的标签。这也是标记/标签接口名字的由来。
Spring提供了许多内置事务管理器实现:
(1)DataSourceTransactionManager:位于org.springframework.jdbc.datasource包中,数据源事务管理器,提供对单个javax.sql.DataSource事务管理,用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事务管理;
(2)JdoTransactionManager:位于org.springframework.orm.jdo包中,提供对单个javax.jdo.PersistenceManagerFactory事务管理,用于集成JDO框架时的事务管理;
(3)JpaTransactionManager:位于org.springframework.orm.jpa包中,提供对单个javax.persistence.EntityManagerFactory事务支持,用于集成JPA实现框架时的事务管理;
(4)HibernateTransactionManager:位于org.springframework.orm.hibernate3包中,提供对单个org.hibernate.SessionFactory事务支持,用于集成Hibernate框架时的事务管理;该事务管理器只支持Hibernate3+版本,且Spring3.0+版本只支持Hibernate 3.2+版本;
(5)JtaTransactionManager:位于org.springframework.transaction.jta包中,提供对分布式事务管理的支持,并将事务管理委托给Java EE应用服务器事务管理器;
OC4JjtaTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对OC4J10.1.3+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持;
(6)WebSphereUowTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对WebSphere 6.0+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持;
(7)WebLogicJtaTransactionManager:位于org.springframework.transaction.jta包中,Spring提供的对WebLogic 8.1+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持。
1.18 TransactionSuspensionNotSupportedException:试图挂起一个事务,但是底层后台不支持事务的挂起时抛出的异常。
1.19 TransactionSystemException:当一个事务系统发生故障时抛出的异常,比如在提交或者回滚时。
1.20 TransactionTimedOutException:当一个事务超时了抛出的异常。
1.21 TransactionUsageException:不适当的使用Spring事务API抛出的异常。
1.22 UnexpectedRollbackException:尝试提交一个事务,但是引发了一个意料之外的回滚抛出的异常。
02 transaction/annotation
2.1 AbstractTransactionManagementConfiguration:配置类(@Configuration)的抽象基类,提供了公共结构用于开启Spring的注解驱动的事务管理能力。
2.2 AnnotationTransactionAttributeSource:完成创建SpringTransactionAnnotationParser、JtaTransactionAnnotationParser、Ejb3TransactionAnnotationParser对象并添加到解析器列表中,以便后面处理对应注解的工作。
2.3 Ejb3TransactionAnnotationParser:策略实现,用于解析EJB3的TransactionAttribute注解。
2.4 EnableTransactionManagement:开启Spring的注解驱动事务管理能力,使用在@Configuration类中。
2.5 Isolation:Isolation 枚举类中定义了五个表示隔离级别的值:
(1)DEFAULT :这是默认值,表示使用底层数据库的默认隔离级别。对大部分数据库而言,通常这值就是: READ_COMMITTED 。
(2)READ_UNCOMMITTED :该隔离级别表示一个事务可以读取另一个事务修改但还没有提交的数据。该级别不能防止脏读和不可重复读,因此很少使用该隔离级别。
(3) READ_COMMITTED :该隔离级别表示一个事务只能读取另一个事务已经提交的数据。该级别可以防止脏读,这也是大多数情况下的推荐值。
(4) REPEATABLE_READ :该隔离级别表示一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。该级别可以防止脏读和不可重复读。
(5)SERIALIZABLE :所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
2.6 JtaTransactionAnnotationParser:策略实现,用于解析parsing JTA(Java Transaction API) 1.2的事务注解。
2.7 Propagation:枚举类中定义了表示传播行为的枚举值:
(1)REQUIRED :如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
(2)SUPPORTS :如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
(3)MANDATORY :如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
(4)REQUIRES_NEW :创建一个新的事务,如果当前存在事务,则把当前事务挂起。
(5)NOT_SUPPORTED :以非事务方式运行,如果当前存在事务,则把当前事务挂起。
(6)NEVER :以非事务方式运行,如果当前存在事务,则抛出异常。
(7)NESTED :若当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;若当前没有事务,则该取值等价于 REQUIRED 。
2.8 ProxyTransactionManagementConfiguration:配置类,该类注册Spring基础架构beans,这些bean是启用基于代理的注解驱动事务管理所必须的,如AnnotationTransactionAttributeSource、BeanFactoryTransactionAttributeSourceAdvisor、TransactionInterceptor。
2.9 SpringTransactionAnnotationParser :策略实现,用于解析Spring事务注解。
策略(Strategy)模式:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
2.10 Transactional:该注解类用于在一个方法或者类上描述一个事务属性。在类级别上应用这个注解(@ Transactional),在默认的在它所有的方法和它所有的子类中应用该注解。
2.11 TransactionAnnotationParser:策略接口,用于解析熟知的事务注解类型。
2.12 TransactionManagementConfigurationSelector:配置启动事务启动(EnableTransactionManagement)时,导入注册的配置bean。
它包括AutoProxyRegistrar和ProxyTransactionManagementConfiguration两大配置块。
(1)AutoProxyRegistrar :负责依赖注入事务的相关属性配置和注入事务入口类(InfrastructureAdvisorAutoProxyCreator类);
(2)ProxyTransactionManagementConfiguration:负责注入事务相关的Bean,包括:
事务切面Bean(BeanFactoryTransactionAttributeSourceAdvisor);
事务配置属性bean(TransactionAttributeSource);
事务拦截器bean(TransactionInterceptor)。
2.13 TransactionManagementConfigurer:被带有@EnableTransactionManagement注解的配置类实现的接口,这些配置类要指定默认的PlatformTransactionManager bean(或者是ReactiveTransactionManager bean),以用于注解驱动事务管理,而不是通过类型进行查找。为什么要这样,比如在容器中现有两个PlatformTransactionManager。
03 transaction/config
3.1 AnnotationDrivenBeanDefinitionParser :org.springframework.beans.factory.xml.BeanDefinitionParser接口的实现类,使得用户可以方便的对所有的基础架构bean开启注解驱动的事务界定。
3.2 JtaTransactionManagerBeanDefinitionParser:解析XML配置元素<tx:jta-transaction-manager>,自动检测WebLogic 和WebSphere服务器,暴露相应的JtaTransactionManager子类。
3.3 JtaTransactionManagerFactoryBean:一个FactoryBean,等同于XML元素<tx:jta-transaction-manager>,自动检测WebLogic和WebSphere服务器,暴露相应的JtaTransactionManager子类。
3.4 TransactionManagementConfigUtils:配置常量,用于子包之间的内部共享。
3.5 TxAdviceBeanDefinitionParser:用于<tx:advice>标签的BeanDefinitionParser。
3.6 TxNamespaceHandler:名字空间处理器,允许使用XML或注解对声明式事务进行配置。
04 transaction/event
4.1 ApplicationListenerMethodTransactionalAdapter:GenericApplicationListener适配器,将对事件的处理委托给带@TransactionalEventListener注解的方法。
4.2 TransactionPhase:枚举类,枚举了事务事件监听器应用的时机。有:BEFORE_COMMIT、AFTER_COMMIT、AFTER_ROLLBACK、AFTER_COMPLETION。
4.3 TransactionalEventListener:一个事件监听器,根据TransactionPhase被调用。如果一个事件没有被活跃的事务所发布,该事件就被丢弃了除非fallbackExecution标识位设置了。如果事务在运行中,事件会根据其进行的阶段被处理。
4.4 TransactionalEventListenerFactory:EventListenerFactory接口实现类,处理带@ TransactionalEventListener注解的方法。
05 transaction/interceptor
5.1 AbstractFallbackTransactionAttributeSource:TransactionAttributeSource接口抽象实现,按如下顺序依次尝试获取事务注解属性:
1)specific target method和method相同签名的targetClass上的那个方法;
2)target class – 也就是参数targetClass;
3)declaring method – 也就是参数method;
4)declaring class/interface – method的声明类/所属类。
并对所发现的事务注解属性进行了缓存。
5.2 BeanFactoryTransactionAttributeSourceAdvisor:创建BeanFactoryTransactionAttributeSourceAdvisor对象,并添加到Spring容器中,后面的功能就交给Spring AOP去处理。
5.3 CompositeTransactionAttributeSource:这是一个集合代理类,其构造方法要求传入一些实现,然后在被调用的时候循环调用那些实现直到获得满意结果
5.4 DefaultTransactionAttribute:Spring通用的事务属性实现类。
5.5 DelegatingTransactionAttribute:TransactionAttribute接口的抽象实现类,将所有的调用委托给给定的目标TransactionAttribute实例。
5.6 MatchAlwaysTransactionAttributeSource:TransactionAttributeSource最简单的实现,对于所有的方法都返回同样的TransactionAttribute。TransactionAttribute可以指定,否则默认为PROPAGATION_REQUIRED(事务传播属性:支持当前事务,如果当前没有事务,就新建一个事务)。
5.7 MethodMapTransactionAttributeSource:在其内部维护了一个Map来根据每个Method来决定TransactionAttribute
5.8 NameMatchTransactionAttributeSource:它是通过方法名的匹配来(可以采用通配符)来寻找TransactionAttribute ,当有多个时使用最长的那一个。
5.9 NoRollbackRuleAttribute:继承自RollbackRuleAttribute,具有和父类RollbackRuleAttribute相反的行为。
5.10 RollbackRuleAttribute:决定一个给定的异常(和其任意的子类)是否应该引发一个回滚。
5.11 RuleBasedTransactionAttribute:TransactionAttribute实现类,通过应用许多回滚规则来计算给定的异常是否要引发事务的回滚,包括正面和负面的。如果没有和该异常相关的规则,使用DefaultTransactionAttribute(在运行时异常时回滚)。
5.12 TransactionalProxy:标记接口,用于手动创建事务代理。
5.13 TransactionAspectSupport:TransactionAspectSupport 是Spring的事务切面逻辑抽象基类,该类实现了事务切面逻辑,但是自身设计为不能被直接使用,而是作为抽象基类被实现子类使用,应用于声明式事务使用场景。TransactionInterceptor,或者 AspectJ切面类AnnotationTransactionAspect.aj,JtaAnnotationTransactionAspect.aj都是继承自该类。
TransactionAspectSupport为实现子类提供的核心工具方法就是#invokeWithinTransaction,该方法的实现会把一个对目标方法的调用包裹(可以理解成AOP中的around模式)在一个事务处理逻辑中。但是该方法何时被调用,就交给实现子类了。
另外TransactionAspectSupport使用了策略设计模式(Strategy)。它会使用一个外部指定的PlatformTransactionManager来执行事务管理逻辑,并且使用一个外部指定的TransactionAttributeSource用来获取事务定义信息,也就是@Transactional这种注解上的信息。
5.14 TransactionAttribute:该接口继承自TransactionDefinition,在父类TransactionDefinition基础上增加了boolean rollbackOn(Throwable ex);函数,判断在给定的异常时是否应该回滚。
5.15 TransactionAttributeEditor:用于事务属性的属性编辑器。接受{PROPAGATION_NAME, ISOLATION_NAME, readOnly,timeout_NNNN,+Exception1,-Exception2}类型的字符串。
5.16 TransactionAttributeSource:策略接口,被TransactionInterceptor使用,用于取回元数据。
5.17 TransactionAttributeSourceAdvisor:TransactionAttributeSource的增强器,用于包含一个事务拦截器,仅用于事务方法。
5.18 TransactionAttributeSourceEditor:属性编辑器,用于将一个字符串转换成TransactionAttributeSource。事务属性字符串必须能被该包中的TransactionAttributeEditor解析。
5.19 TransactionAttributeSourcePointcut:切点实现类。Pointcut拦截住了方法,然后使用TransactionAttributeSource去方法和类上获取事务属性,如果能获取到,说明此方法需要参与事务,则进行事务增强,反之则不增强。
5.20 TransactionInterceptor:TransactionInterceptor是Spring框架内置实现的一个MethodInterceptor,用于声明式事务管理,使用Spring事务基础设施org.springframework.transaction.PlatformTransactionManager。
作为一个MethodInterceptor,TransactionInterceptor会被包裹在使用了事务注解的bean组件外面形成该组件的代理对象,当调用相应使用事务注解的方法时,TransactionInterceptor的方法拦截器逻辑会被应用,从而完成相应的事务管理。
TransactionInterceptor继承自TransactionAspectSupport。主要的事务管理逻辑实现在该基类中。TransactionInterceptor自身主要是实现接口MethodInterceptor定义的方法invoke,触发被TransactionAspectSupport事务拦截逻辑包围的目标方法的调用。
关于TransactionInterceptor如何被引入到应用,ProxyTransactionManagementConfiguration是一个很好的例子。在该配置类中,TransactionInterceptor被作为一个bean定义注册到容器,它会被ProxyTransactionManagementConfiguration注册到容器的另外一个bean transactionAdvisor使用;应用启动时Spring的自动代理机制会发现transactionAdvisor以及它所使用的TransactionInterceptor,并将该TransactionInterceptor在创建相应bean的代理对象时包裹到bean外部。
5.21 TransactionProxyFactoryBean:专门为目标Bean生成事务代理的工厂Bean。 每个TransactionProxyFactoryBean为一个目标Bean生成一个事务代理Bean,事务代理的方法改写了目标Bean的方法,就是在目标Bean的方法执行之前加入开始事务,在目标Bean的方法正常结束之前提交事务,如果遇到特定异常则回滚。
06 transaction/jta
6.1 JtaAfterCompletionSynchronization:适配一个JTA Synchronization,在JTA事务完成后调用Spring TransactionSynchronization的afterCommit/ afterCompletion回调函数。
6.2 JtaTransactionManager:PlatformTransactionManager接口关于JTA(Java Transaction API)的实现类。提供对分布式事务管理的支持,并将事务管理委托给Java EE应用服务器事务管理器。
6.3 JtaTransactionObject:JTA事务对象,表示一个javax.transaction.UserTransaction。作为一个事务对象被Spring的JtaTransactionManager使用。这是一个SPI类,不打算被应用使用。
6.4 ManagedTransactionAdapter:托管JTA事务句柄的适配器,采用一个JTA TransactionManager引用,为其创建一个JTA Transaction句柄。
6.5 SimpleTransactionFactory:TransactionFactory策略接口的默认实现类。封装了一个标准的JTA TransactionManager。
6.6 SpringJtaSynchronizationAdapter:实现JTA Synchronization接口的适配器,委托给一个Spring TransactionSynchronization。
6.7 TransactionFactory:策略接口,基于指定的事务特征创建JTA Transaction对象。其默认的实现类是SimpleTransactionFactory,简单封装了一个标准的JTA TransactionManager。
6.8 UserTransactionAdapter:一个JTA UserTransaction句柄适配器,接受一个TransactionManager引用,为其创建一个JTA UserTransaction句柄。
6.9 WebLogicJtaTransactionManager:Spring提供的对WebLogic 8.1+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持。
6.10 WebSphereUowTransactionManager:Spring提供的对WebSphere 6.0+应用服务器事务管理器的适配器,此适配器用于对应用服务器提供的高级事务的支持。
07 transaction/reactive
7.1 AbstractReactiveTransactionManager:抽象基类,实现了Spring的标准响应式事务工作流程,作为具体的platform事务管理器的基类。
该基类提供了以下的工作流处理:
1) 判断是否存在一个事务;
2) 应用相应的事务传播行为;
3) 根据需要挂起或重启事务;
4) 提交事务时检查rollback-only标记;
5) 在回滚中进行相应的更改;
6) 触发注册过的同步回调。
子类需要为指定事务的状态实现指定的模板方法,比如:开始、挂起、重启、提交、回滚。这些重要的方法现在还是抽象方法,需要在子类中进行实现。其他的一些方法提供了默认实现,也可以实现覆盖原有的默认实现。
7.2 GenericReactiveTransaction:ReactiveTransaction接口的默认实现,被AbstractReactiveTransactionManager使用。
保存了所有的状态信息,这些信息会被AbstractReactiveTransactionManager内部使用,包括一个由具体事务管理器实现类决定的通用事务对象。
7.3 ReactiveResourceSynchronization:TransactionSynchronization接口的抽象实现类,通过TransactionSynchronizationManager管理一个资源对象。
7.4 TransactionalOperator:如果是使用的是命令式编程,Spring使用TransactionTemplate 来完成编程式事务管理,如果是响应式编程,那么使用TransactionalOperator。该类简化了编程式事务管理和事务异常的处理。
7.5 TransactionalOperatorImpl:TransactionalOperator接口的实现类,简化了编程式事务管理和事务异常的处理。
7.6 TransactionCallback:回调接口,用于响应式事务代码。
7.7 TransactionContext :可变的事务上下文,封装了事务同步和在单个事务范围内的资源。
7.8 TransactionContextHolder:响应式事务上下文可变的句柄。这个句柄保存了对一个个的TransactionContext的引用。
7.9 TransactionContextManager:注册和获取事务上下文。
7.10 TransactionSynchronization:用于响应式事务同步回调的接口,被AbstractReactiveTransactionManager所支持。
7.11 TransactionSynchronizationManager:为每个订阅的上下文管理资源和事务同步。被资源管理代码使用,但不是用于典型的应用代码。
7.12 TransactionSynchronizationUtils:功能方法,用于在所有现有注册的synchronizations中,触发指定的TransactionSynchronization回调方法。
08 transaction/support
8.1 AbstractPlatformTransactionManager:AbstractPlatformTransactionManager抽象类,实现了PlatformTransactionManager接口。负责实现整个事务管理和运行过程中的公共行为和通用实现逻辑,提供了一些默认的方法实现,比如提交和回滚的逻辑实现。
一般自定义事务管理类的时候,不是直接去实现PlatformTransactionManager接口,而是通过继承AbstractPlatformTransactionManager来完成,AbstractPlatformTransactionManager的作用就相当于一个模板,提供固有的方法实现。通用的事务处理流程框架是由AbstractPlatformTransactionManager来提供的,具体的底层事务处理实现,由PlatformTransactionManager的具体实现类来实现,如 DataSourceTransactionManager 、JtaTransactionManager和 HibernateTransactionManager等。
AbstractPlatformTransactionManager抽象类提供了以下工作流程处理:
1)确定如果有现有的事务;
2)应用适当的传播行为;
3)如果有必要暂停和恢复事务;
4)提交时检查rollback-only标记;
5)应用适当的修改当回滚(实际回滚或设置rollback-only)
6)触发同步回调注册(如果事务同步是激活的)。
子类必须实现为特定的事务状态实现模板方法。例如:开始、挂起、重启、提交、回滚。这些重要的方法是抽象方法,需要在子类中进行实现,其余的提供了默认实现,子类也可覆盖实现。
8.2 AbstractTransactionStatus:对于PlatformTransactionManager有默认的抽象类方法实现模板,那TransactionStatus也有,其对应的模板实现类就是AbstractTransactionStatus。
8.3 CallbackPreferringPlatformTransactionManager:PlatformTransactionManager接口的拓展,暴露了一个方法,用于使用事务执行一个给定的回调。
8.4 DefaultTransactionDefinition:TransactionDefinition接口的默认实现类,体用了bean类型的配置和合理的默认值(PROPAGATION_REQUIRED, ISOLATION_DEFAULT,TIMEOUT_DEFAULT,readOnly=false)。作为TransactionTemplate和DefaultTransactionAttribute的父类。
8.5 DefaultTransactionStatus:TransactionDefinition没有提供对应的抽象类,而是直接提供了一个默认的实现类DefaultTransactionDefinition。我感觉是因为TransactionDefinition的主要的内容是属性,方法比较简单,就没有必要提供一个抽象模板实现了。
8.6 DelegatingTransactionDefinition:实现TransactionDefinition接口的抽象类,将所有的调用委托给给定的目标TransactionDefinition实例。
8.7 ResourceHolder:被资源持有者实现的通用接口。允许需要的时候Spring事务架构内省和重置这些资源持有者。
8.8 ResourceHolderSupport:资源句柄支持类,作用在于方便ResourceHolder接口的实现。
8.9 ResourceHolderSynchronization:实现了TransactionSynchronization接口,通过TransactionSynchronizationManager来管理资源句柄。用来同步资源状态的,这里的资源就是Spring 事务框架中的资源的概念,就是JDBC里的Connection,Hibernate里的Session,JPA里的EntityManager,Kafka里的Producer。
8.10 ResourceTransactionDefinition:TransactionDefinition接口的拓展,表示一个资源事务,特别是事务资源是否准备好局部优化。
8.11 ResourceTransactionManager:PlatformTransactionManager接口的拓展接口,表示一个本地的资源事务管理器,操作单个的目标资源。这些事务管理器和JTA事务管理器不同,它们不为一个公开数字的资源使用XA事务等级,而是专注利用本机功能,简化单个目标资源。
8.12 SimpleTransactionScope:基于事务的Scope接口的实现类。
8.13 SimpleTransactionStatus:TransactionStatus接口的简单实现类。继承自AbstractTransactionStatus,增加了一个"newTransaction"标识。
8.14 SmartTransactionObject:用于被事务对象实现的接口,这些事务对象能够返回一个内部的rollback-only标识,通常从另一个参与和标记为rollback-only的事务获取。
8.15 TransactionCallback:回调接口,用于事务代码,和TransactionTemplate的execute方法一起使用,常作为一个方法实现中的匿名类。执行事务处理后有返回值,如find要返回结果集(List)。
8.16 TransactionCallbackWithoutResult:方便对TransactionCallback接口的实现,允许实现一个不带返回值的doInTransaction版本,比如不需要返回statement,如save、update、delete等等。
8.17 TransactionOperations:指定了基本的事务执行操作的接口。被TransactionTemplate所实现。一般不直接使用,但是可以方便测试,因为其可容易的mocked或stubbed。
8.18 TransactionSynchronization:用于事务同步的接口。被AbstractPlatformTransactionManager支持。
8.19 TransactionSynchronizationAdapter:TransactionSynchronization简单适配器,包含了方法的空实现。
8.20 TransactionSynchronizationManager:对每个线程的资源和事务同步进行管理。被资源管理代码使用,一般不被应用代码使用。
8.21 TransactionSynchronizationUtils:功能函数,用于在所有当前注册过的synchronizations触发指定的TransactionSynchronization回调方法。
8.22 TransactionTemplate:TransactionTemplate的编程式事务管理是使用模板方法设计模式对原始事务管理方式的封装。TransactionTemplate主要依赖于execute(TransactionCallback<T> action)方法执行事务管理。
Spring可以支持编程式事务和声明式事务。
(1)Spring提供的最原始的事务管理方式是基于TransactionDefinition、PlatformTransactionManager、TransactionStatus 编程式事务。
(2)而TransactionTemplate的编程式事务管理是使用模板方法设计模式对原始事务管理方式的封装。需要自己手动在每个业务方法中实现事务。
(3)基于 @Transactional 的方式将声明式事务管理简化到了极致。
8.23 WithoutTransactionOperations:TransactionOperations接口的实现类,在没有实际事务情况下执行一个给定的TransactionCallback。
参考:https://www.cnblogs.com/davidwang456/p/4309038.html
拓展阅读:
Spring框架之beans源码完全解析
Spring框架之AOP源码完全解析
Spring框架之jdbc源码完全解析
Spring源码深度解析之数据库连接JDBC
Spring框架之jms源码完全解析
Spring框架之事务源码完全解析
Spring源码深度解析之事务
Spring源码深度解析之Spring MVC
Spring框架之websocket源码完全解析
WebSocket协议中文版
Spring框架之spring-web web源码完全解析
Spring框架之spring-web http源码完全解析
Spring框架之spring-webmvc源码完全解析
博众家之所长,集群英之荟萃。遴选各IT领域精品雄文!
欢迎关注“IT架构精选”