Spring事务总结

参考

首先,如果整个系统要能实现事务,需要两个方面:

  • Spring开启了事务
  • MySQL 数据库默认使用支持事务的innodb引擎

1.什么是事务?

事务是逻辑上的一组操作,要么都执行,要么都不执行。

2. 事物的特性(ACID)了解么?

  • 原子性: 事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
  • 一致性: 执行事务前后,数据保持一致;
  • 隔离性: 并发访问数据库时,一个用户的事物不被其他事务所干扰也就是说多个事务并发执行时,一个事务的执行不应影响其他事务的执行;
  • 持久性: 一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。

3. 详谈 Spring 对事务的支持

再提醒一次:你的程序是否支持事务首先取决于数据库 ,比如使用 MySQL 的话,如果你选择的是 innodb 引擎,那么恭喜你,是可以支持事务的。但是,如果你的 MySQL 数据库使用的是 myisam 引擎的话,那不好意思,从根上就是不支持事务的。

这里再多提一下一个非常重要的知识点: MySQL 怎么保证原子性的?

  • 通过记录**回滚日志(undo log)**进行回滚
  • 所有操作记录到回滚日志(undo log)
  • 同时**回滚日志(undo log)**可以定时持久化到磁盘上

3.1. Spring 支持两种方式的事务管理

1).编程式事务管理

通过 TransactionTemplate或者TransactionManager手动管理事务,实际应用中很少使用,但是对于你理解 Spring 事务管理原理有帮助。

try catch的方式,如果如果失败,就在catch中回滚

使用TransactionTemplate 进行编程式事务管理的示例代码如下:

@Autowired
private TransactionTemplate transactionTemplate;
public void testTransaction() {transactionTemplate.execute(new TransactionCallbackWithoutResult() {@Overrideprotected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {try {// ....  业务代码} catch (Exception e){//回滚transactionStatus.setRollbackOnly();}}});
}

使用 TransactionManager 进行编程式事务管理的示例代码如下:

@Autowired
private PlatformTransactionManager transactionManager;public void testTransaction() {TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());try {// ....  业务代码transactionManager.commit(status);} catch (Exception e) {transactionManager.rollback(status);}
}

2)声明式事务管理

推荐使用(代码侵入性最小),实际是通过 AOP 实现(基于@Transactional 的全注解方式使用最多)。

使用 @Transactional注解进行事务管理的示例代码如下:

@Transactional(propagation=propagation.PROPAGATION_REQUIRED)
public void aMethod {//do somethingB b = new B();C c = new C();b.bMethod();c.cMethod();
}

3.2. Spring 事务管理接口介绍

Spring 框架中,事务管理相关最重要的 3 个接口如下:

  • PlatformTransactionManager(平台)事务管理器,Spring 事务策略的核心。 提供了获得,提交,回滚的接口方法。
  • TransactionDefinition事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)
  • TransactionStatus事务运行状态。

我们可以把 PlatformTransactionManager 接口可以被看作是事务上层的管理者,而 TransactionDefinitionTransactionStatus 这两个接口可以看作是事物的描述。

PlatformTransactionManager 会根据 TransactionDefinition 的定义比如事务超时时间、隔离界别、传播行为等来进行事务管理 ,而 TransactionStatus 接口则提供了一些方法来获取事务相应的状态比如是否新事务、是否可以回滚等等。

3.2.1. PlatformTransactionManager:事务管理接口

Spring 并不直接管理事务,而是提供了多种事务管理器 。Spring 事务管理器的接口是: PlatformTransactionManager

通过这个接口,Spring 为各个平台如 JDBC(DataSourceTransactionManager)、Hibernate(HibernateTransactionManager)、JPA(JpaTransactionManager)等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。

PlatformTransactionManager接口中定义了三个方法:

package org.springframework.transaction;import org.springframework.lang.Nullable;public interface PlatformTransactionManager {//获得事务TransactionStatus getTransaction(@Nullable TransactionDefinition var1) throws TransactionException;//提交事务void commit(TransactionStatus var1) throws TransactionException;//回滚事务void rollback(TransactionStatus var1) throws TransactionException;
}

TransactionStatus 接口接口内容如下:

public interface TransactionStatus{boolean isNewTransaction(); // 是否是新的事物boolean hasSavepoint(); // 是否有恢复点void setRollbackOnly();  // 设置为只回滚boolean isRollbackOnly(); // 是否为只回滚boolean isCompleted; // 是否已完成
}

3.2.2. TransactionDefinition:事务属性

事务属性包含了 5 个方面:

隔离级别:(mysql innodb 和 spring 的默认隔离级别都是 可重复读)

  • 根据数据隔离级别 :使用后端数据库默认的隔离级别,MySQL 默认采用的 REPEATABLE_READ 隔离级别 Oracle 默认采用的 READ_COMMITTED 隔离级别.
  • 读未提交 :最低的隔离级别,使用这个隔离级别很少,因为它允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
  • 读已提交 : 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
  • 可重复读 : 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
  • 序列化 : 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、
  • 不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

3.3.3. 事务超时属性

所谓事务超时,就是指**一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。**在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒,默认值为-1。

3.3.3. 事务只读属性(若类型为readonly,相当于对数据加了读锁)

package org.springframework.transaction;import org.springframework.lang.Nullable;public interface TransactionDefinition {......// 返回是否为只读事务,默认值为 falseboolean isReadOnly();}

对于只有读取数据查询的事务,可以指定事务类型为 readonly,即只读事务。只读事务不涉及数据的修改,数据库会提供一些优化手段,适合用在有多条数据库查询操作的方法中。

3.3.4. 事务回滚规则

这些规则定义了哪些异常会导致事务回滚而哪些不会。默认情况下,事务只有遇到运行期异常(RuntimeException 的子类)时才会回滚,Error 也会导致事务回滚。

如果你想要回滚你定义的特定的异常类型的话,可以这样:

@Transactional(rollbackFor= MyException.class)

3.4. @Transactional 注解使用详解

1) @Transactional 的作用范围

  1. 方法 :推荐将注解使用于方法上,不过需要注意的是:该注解只能应用到 public 方法上,否则不生效。
  2. :如果这个注解使用在类上的话,表明该注解对该类中所有的 public 方法都生效。
  3. 接口 :不推荐在接口上使用。

2) @Transactional 的常用配置参数。5个参数,事务传播行为,隔离级别,超时时间,隔离只读属性,回滚的规则

@Transactional注解源码如下,里面包含了基本事务属性的配置:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {@AliasFor("transactionManager")String value() default "";@AliasFor("value")String transactionManager() default "";Propagation propagation() default Propagation.REQUIRED;Isolation isolation() default Isolation.DEFAULT;int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;boolean readOnly() default false;Class<? extends Throwable>[] rollbackFor() default {};String[] rollbackForClassName() default {};Class<? extends Throwable>[] noRollbackFor() default {};String[] noRollbackForClassName() default {};}

@Transactional 的常用配置参数总结(只列巨额 5 个我平时比较常用的):

属性名 说明
propagation 事务的传播行为,默认值为 REQUIRED,可选的值在上面介绍过
isolation 事务的隔离级别,默认值采用 DEFAULT,可选的值在上面介绍过
timeout 事务的超时时间,默认值为-1(不会超时)。如果超过该时间限制但事务还没有完成,则自动回滚事务。
readOnly 指定事务是否为只读事务,默认值为 false。
rollbackFor 用于指定能够触发事务回滚的异常类型,并且可以指定多个异常类型。

3)@Transactional 事务注解原理 - AOP实现

面试中在问 AOP 的时候可能会被问到的一个问题。简单说下吧!

我们知道,@Transactional 的工作机制是基于 AOP 实现的,AOP 又是使用动态代理实现的。如果目标对象实现了接口,默认情况下会采用 JDK 的动态代理,如果目标对象没有实现了接口,会使用 CGLIB 动态代理。

  • @Transactional注解的类,创建代理类。
  • 实际调用的是TransactionInterceptor 类中的 invoke()方法
  • 这个方法的作用就是在目标方法之前开启事务,方法执行过程中如果遇到异常的时候回滚事务,方法调用完成之后提交事务。

4 事务传播行为(方法相互调用时,事务的处理):

当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。在TransactionDefinition定义中包括了如下几个表示传播行为的常量:

支持当前事务的情况:

  • REQUIRED: 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  • SUPPORTS: 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
  • MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)

不支持当前事务的情况:

  • REQUIRES_NEW: 创建一个新的事务,如果当前存在事务,则把当前事务放到最后,先执行被调用方法的事务。
  • NOT_SUPPORTED: 以非事务方式运行,如果当前存在事务,则把当前事务放到最后。简单来说外层有事务,内层不受事务影响。
  • NEVER: 以非事务方式运行,如果当前存在事务,则抛出异常。

嵌套循环事务

  • NESTED:如果没有事务,就新建一个事务;如果有,就在当前事务中嵌套其他事务。

NESTED解释:外围方法没有事务:这种情况跟REQUIRED是一样的,会新建一个事务。

外围方法如果存在事务:这种情况就会嵌套事务。所谓嵌套事务,大意就是,外围事务回滚,内嵌事务一定回滚,而内嵌事务可以单独回滚而不影响外围主事务和其他子事务。

spring事务详解相关推荐

  1. Spring源码(八):Spring事务详解

    Spring事务详解 一.事务执行流程 二.Spring事务切面 三.事务切面的Pointcut和Advice 四.注解事务的源码分析 五.Sping事务的传播属性 六.Sping事务的异常校验 七. ...

  2. Spring事务详解与使用

    Spring事务核心对象 J2EE开发使用分层设计的思想进行,对于简单的业务层转调数据层的单一操作,事务开启在业务层或者数据层并无太大差别,当业务中包含多个数据层的调用时,需要在业务层开启事务,对数据 ...

  3. Spring高级之Spring事务详解(用法、传播行为、隔离级别、只读事务、事务条件)

    前言 这是之前开始学spring的时候的笔记,现在添加了一些理解,然后把他搬到博客上来. 事务概述: 这里仅对数据库事务进行一个概述,要详细的可以查询相关文章 在JavaEE企业级开发的应用领域,为确 ...

  4. Spring 体系结构详解

    Spring 体系结构详解 核心容器(Core Container) Core和Beans模块提供了Spring最基础的功能,提供IOC和依赖注入特性.这里的基础概念是BeanFactory,它提供对 ...

  5. struts2+hibernate+spring配置详解

    #struts2+hibernate+spring配置详解 struts2+hibernate+spring配置详解 哎 ,当初一个人做好难,现在终于弄好了,希望自学这个的能少走些弯路. 以下是自己配 ...

  6. SpringBoot事务详解

    文章目录 一.简介 1.介绍 2.事务特点 3.事务实现方式 3.1 MySql事务实现方式 3.2 SpringBoot实现机制 二.@Transactional详解 1.@Transactiona ...

  7. java JDBC事务和JTA事务详解

    什么是事务? 事务其实就是一套数据库操作集合,说到事务就不得不说它的四大特性(A C I D):原子性,一致性,隔离性,持久性.事务的原子性表示事务要么被全部执行,要么被全部不执行.如果事务下的子事务 ...

  8. Spring入门详解

    typora-copy-images-to: upload Spring入门详解 Spring框架是Java开发中最常用的框架,功能非常强大 源码下载:Spring Framework jar包.文档 ...

  9. 什么是ZooKeeper?可以做什么?ZooKeeper分布式事务详解篇

    前言 什么是ZooKeeper,你真的了解它吗.我们一起来看看吧~ 一.什么是 ZooKeeper? ZooKeeper 是 Apache 的一个顶级项目,为分布式应用提供高效.高可用的分布式协调服务 ...

最新文章

  1. (0030) iOS 开发之跳转之转场动画
  2. 使用机器学习检测TLS 恶意加密流——业界调研***有开源的数据集,包括恶意证书的,以及恶意tls pcap报文***...
  3. RSGAN:对抗模型中的“图灵测试”思想
  4. c++读取utf8文件_经常在日常工作中处理统一码文件(or其他编码)?这篇必读
  5. 数字信号处理基础知识00
  6. MySQL存储过程语句(if,while)的使用
  7. 免费生成十字绣字体_十字绣鞋垫图案 手工鞋垫历史长
  8. redis3.2版本protected-mode参数
  9. xp 无法关闭计算机,电脑xp系统关不了机怎么解决
  10. linux镜像下载与安装
  11. 手机变身电脑摄像头 Droidcam使用
  12. 通俗易懂的图解机器学习之机器学习概论
  13. sax解析xml详解
  14. 免费云服务器获取方法 云服务器购买
  15. 就业季必看的职业规划
  16. 南京标志设计-logo商标设计-企业VI形象识别系统
  17. 江苏发展大会上有哪些科技界大佬,他们的“隐私”你知道多少?
  18. 如何查看计算机所连接的打印机
  19. 股权转让项目:厦门古龙温泉山庄开发有限公司60%股权转让
  20. 什么是横向扩展、纵向扩展?

热门文章

  1. 使用Canvas绘制背景图
  2. 用FastJson将JSON字符串转Json
  3. Android四大组件之Activity详解
  4. 半年后继续捡起,,,
  5. 手机上怎么记录恋爱天数?用便签记录情侣相恋天数
  6. 水冷计算机主机,一种水冷计算机主机的制作方法
  7. git revert 还原命令——反向更改(抵消更改)
  8. Swap()函数的详细解析
  9. MFC 文件分析工具,弹出“遇到不适当的参数”对话框
  10. HTML中简单的form元素及属性: