Spring事务的本质是对数据库事务的封装支持,没有数据库对事务的支持,Spring本身无法提供事务管理功能。对于用JDBC操作数据库想要用到事务,必须经过获取连接——》开启事务——》执行CRUD操作——》提交/回滚事务——》关闭连接几部分操作。使用Spring管理事务后,可以省掉自己写代码开启、提交/回滚事务的操作。

Spring事务通过AOP动态代理实现,使用上通常要先在配置文件中开启事务,然后通过xml文件或注解配置要执行注解的类方法,然后在调用对应类实例方法时,Spring会自动生成代理,在调用前设置事务操作、调用方法后进行事务回滚或提交操作。

Spring事务的SPI(服务提供接口,给第三方服务实现类提供的接口实现要求)接口主要有:TransactionDefinition、PlatformTransactionManager、TransactionStatus。

1、org.springframework.transaction.TransactionDefinition,它用于定义一个事务。它包含了事务的静态属性,比如:事务传播行为、隔离级别、超时时间等等。

Spring 为我们提供了一个默认的实现类:DefaultTransactionDefinition,该类适用于大多数情况。如果该类不能满足需求,可以通过实现 TransactionDefinition 接口来实现自己的事务定义。

2、org.springframework.transaction.PlatformTransactionManager,用于执行具体的事务操作,方法列表如下:全部抛出TransactionException异常

PlatformTransactionManager 的主要实现类大致如下:

根据底层所使用的不同的持久化 API 或框架,使用如下:

DataSourceTransactionManager:适用于使用JDBC和iBatis进行数据持久化操作的情况。

HibernateTransactionManager:适用于使用Hibernate进行数据持久化操作的情况。

JpaTransactionManager:适用于使用JPA进行数据持久化操作的情况。

另外还有JtaTransactionManager 、JdoTransactionManager、JmsTransactionManager等等。

如果我们使用JTA进行事务管理,我们可以通过 JNDI 和 Spring 的 JtaTransactionManager 来获取一个容器管理的 DataSource。JtaTransactionManager 不需要知道 DataSource 和其他特定的资源,因为它将使用容器提供的全局事务管理。而对于其他事务管理器,比如DataSourceTransactionManager,在定义时需要提供底层的数据源作为其属性,也就是 DataSource。与 HibernateTransactionManager 对应的是 SessionFactory,与 JpaTransactionManager 对应的是 EntityManagerFactory 等等。

下面分析DataSourceTransactionManager,指明dataSourcce:javax.sql.DataSource。

注入dataSourcce:

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource" />

</bean>

3、TransactionStatus

PlatformTransactionManager.getTransaction(…) 方法返回一个 TransactionStatus 对象。返回的TransactionStatus 对象可能代表一个新的或已经存在的事务(如果在当前调用堆栈有一个符合条件的事务)。TransactionStatus 接口提供了一个简单的控制事务执行和查询事务状态的方法。

TransactionStatus 接口中定义的主要方法

public  interface TransactionStatus{

boolean isNewTransaction();

void setRollbackOnly();

boolean isRollbackOnly();

}

事务的隔离级别

默认是数据库事务的隔离级别,大部分数据库是读提交(可解决脏读问题,事务未提交前被数据被其它事务读到),MySQL 是可重复读(一个事务中间进行了两次数据读操作,因为两次之间有其它事务对数据进行了update,而导致两次读取的数据不一致),最高的隔离级别是串读(可解决幻读问题,一个事务读了两次某一范围的数据,中间其它事务对这一范围数据做了增加或删除操作而导致前后读到的数据条数不一致。与不可重复读的区别时前者是范围内数据受到增加或删除影响,需要锁表解决,后者是受到数据修改的影响,可以通过锁行解决)

事务的传播特性

常用的传播特性有PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW、PROPAGATION_NESTED三种,要注意它们之间的区别。

使用嵌套事务的场景有两点需求:

  1. 需要事务BC与事务AD一起commit,即:作为事务AD的子事务,事务BC只有在事务AD成功commit时(阶段3成功)才commit。这个需求简单称之为“联合成功”。这一点PROPAGATION_REQUIRED可以做到。
  2. 需要事务BC的rollback不(无条件的)影响事务AD的commit。这个需求简单称之为“隔离失败”。这一点PROPAGATION_REQUIRES_NEW可以做到。

使用PROPAGATION_REQUIRED满足需求1,但子事务BC的rollback会无条件地使父事务AD也rollback,不能满足需求2。

使用PROPAGATION_REQUIRES_NEW满足需求2,但子事务(这时不应该称之为子事务)BC是完全新的事务上下文,父事务(这时也不应该称之为父事务)AD的成功与否完全不影响BC的提交,不能满足需求1。

同时满足上述两条需求就要用到PROPAGATION_NESTED了。PROPAGATION_NESTED在事务AD执行到B点时,设置了savePoint(关键)。

当BC事务成功commit时,PROPAGATION_NESTED的行为与PROPAGATION_REQUIRED一样。只有当事务AD在D点成功commit时,事务BC才真正commit,如果阶段3执行异常,导致事务AD rollback,事务BC也将一起rollback ,从而满足了“联合成功”。

当阶段2执行异常,导致BC事务rollback时,因为设置了savePoint,AD事务可以选择与BC一起rollback或继续阶段3的执行并保留阶段1的执行结果,从而满足了“隔离失败”。

PROPAGATION_REQUIRED

Spring事务原理的更多相关文章

  1. Spring事务原理分析-部分二

    Spring事务原理分析-部分二 说明:这是我在蚂蚁课堂学习了余老师Spring手写框架的课程的一些笔记,部分代码代码会用到余老师的课件代码.这不是广告,是我听了之后觉得很好. 课堂链接:Spring ...

  2. Spring事务原理分析-部分一

    Spring事务原理分析-部分一 什么事务 事务:逻辑上的一组操作,组成这组操作的各个单元,要么全都成功,要么全都失败. 事务基本特性 ⑴ 原子性(Atomicity) 原子性是指事务包含的所有操作要 ...

  3. 深入理解 Spring 事务原理

    本文由码农网 – 吴极心原创,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 一.事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供 ...

  4. 深入理解 Spring 事务原理【转】

    本文转自码农网 – 吴极心原创  连接地址:http://www.codeceo.com/article/spring-transactions.html 一.事务的基本原理 Spring事务的本质其 ...

  5. 事务之四:Spring事务--原理

    一.Spring事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: ...

  6. 理解 Spring 事务原理

    转载:https://www.jianshu.com/p/4312162b1458 一.事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事 ...

  7. Spring事务原理一探

    概括来讲,事务是一个由有限操作集合组成的逻辑单元.事务操作包含两个目的,数据 一致以及操作隔离.数据一致是指事务提交时保证事务内的所有操作都成功完成,并且 更改永久生效:事务回滚时,保证能够恢复到事务 ...

  8. 一文带你深入浅出Spring 事务原理

    Spring事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 获 ...

  9. Spring事务原理分析--手写Spring事务

    一.基本概念和原理 1.Spring事务 基于AOP环绕通知和异常通知的 2.Spring事务分为编程式事务.声明事务.编程事务包括注解方式和扫包方式(xml) Spring事务底层使用编程事务(自己 ...

  10. 【Spring】看了这篇Spring事务原理,我才知道我对Spring事务的误解有多深!

    写在前面 有很多小伙伴们留言说,冰河,你能不能写一篇关于Spring事务的文章呢?我:可以啊,安排上了!那还等什么呢?走起啊!! 事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有 ...

随机推荐

  1. 安装xampp出错,windows找不到-n ?

    安装xampp出错,windows找不到-n ? https://www.zhihu.com/question/47248695/answer/105042516 尝试解决步骤 1.安装Microso ...

  2. javascript中的词法分析

    词法分析 JavaScript中在调用函数的那一瞬间,会先进行词法分析. 词法分析的过程: 当函数调用的前一瞬间,会先形成一个激活对象:Avtive Object(AO),并会分析以下3个方面: 1: ...

  3. weex中css不能使用子元素选择器

    weex中css不能使用子元素选择器 刚入手可能会有错误,有误导地方请谅解,不过都是亲身踩坑

  4. [poj P2482] Stars in Your Window

    [poj P2482] Stars in Your Window Time Limit: 1000MS  Memory Limit: 65536K Description Fleeting time ...

  5. Winform关于未找到元数据文件.exe和不包含适合于入口点的静态“Main”方法

    在三层架构中ItcastCaterModel项目是被其他项目引用的,所以输出类型为类库.

  6. vscode 快捷键

    ctrl+/   单行注释:// 若要多行注释://,先选中这些要注释的行,再按ctrl+/ shift+Alt+A 多行注释 撤销刚才的操作:Ctrl+Z 恢复刚才的操作:Ctrl+Shift+Z ...

  7. windows10下安装mysql-8.0.15-winx64以及连接服务器过程中遇到的一些问题

    一.下载安装配置mysql-8.0.15 1.官网(https://dev.mysql.com/downloads/mysql/)下载zip包 2.解包到我的D:\mysql目录下 3.为mysql配 ...

  8. Saiku免登录嵌入其他系统使用(十一)

    Saiku免登录嵌入其他系统使用 Saiku可通过iframe嵌入其他系统使用,但是正常情况下都需要先登录系统,然后还需要登录saiku,最后才能访问saiku中的数据 下面来讲解一下如何使Saiku ...

  9. ubuntu1604使用之旅——安装samba

    1.安装samba sudo apt-get install samba 2.安装sambaclient sudo apt-get install smbclient 3.修改配置文件 sudo vi ...

  10. linux中ls -l介绍

    [root@localhost ~]# ls -l 总计 152 -rw-r--r-- 1 root root 2915 08-03 06:16 a -rw------- 1 root root 10 ...