Spring的事务管理

Java基础

浏览数:291

2019-2-23

事务简介

  • 事务:一系列操作,使数据库从一个状态转换到另一个状态,且保证要么全部成功要么全部失败。
  • 事务满足 ACID 原则:
    • 原子性:不可分割,要么全部成功,要么全部失败
    • 一致性:从一个状态到另一个状态
    • 隔离性:正确提交前,可能到结果不应显示给其他事务
    • 持久性:提交后,永久保存在数据库中

Java事务

  • 在Java编写的程序实现ACID操作,把数据库的增删改查的事务操作转移到Java代码中控制。
  • Java事务机制和原理就是确保数据库操作的ACID特性。

Java事务实现模式

  • Java事务类型
    • JDBC事务:局限在一个数据库连接内。
    • JTA(Java Transaction API)事务:与实现无关的,与协议无关的API。可跨多个数据库或多个DAO。
    • 容器事务:应用服务器提供的。

Spring事务核心接口

image

Spring事务属性定义

事务属性

  • 传播行为 int getPropagationBehavior()
  • 隔离规则 int getIsolationLevel()
  • 回滚规则
  • 事务超时 int getTimeout()
  • 是否只读?boolean isReadOnly()

隔离规则

  • 脏读:事务没提交,被提前读取。
  • 不可重复读:两次读取数据不一致。
  • 幻读:事务不是独立执行时发生的一种非预期现象。比如第一个事务修改表中数据全部为男的,第二个事务插入了一个女的,第一个事务再次读取全表发现怎么还有个女的。

事务隔离级别:定义了一个事务可能受其他并发事务影响的程度。

  • ISOLATION_DEFAULT
  • ISOLATION_READ_UNCOMMITTED 脏读,不可重复度,幻读
  • ISOLATION_READ_COMMITTED 避免脏读,仍然会有不可重复读,幻读
  • ISOLATION_REPEATABLE_READ 避免脏读,不可重复读,任然会有幻读
  • ISOLATION_SERIALIZABLE 全部避免,也是最慢的

事务传播行为

  • 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播;
  • spring的7种传播行为:
    • PROPAGATION_RREQUIRED 当前方法必须运行在事务中。如果不存在事务,则新启动一个事务
    • PROPAGATION_RSUPPORTS 当前方法不需要事务上下文。如果存在事务则在事务中运行
    • PROPAGATION_RMANDATORY 当前方法必须运行在事务中。如果不存在事务,则抛出异常
    • PROPAGATION_RREQUIRED_NEW 当前方法必须运行在他自己的事务中,一个新事务会被启动。如果存在当前事务,在该方法执行期间会被挂起。
    • PROPAGATION_RNOT_SUPPORTED 该方法不应该运行在事务中。如果存在事务,在该方法运行期间则被挂起。
    • PROPAGATION_RNEVER 当前方法不应该运行在事务上下文。如果当前正有一个事务在运行,则会抛异常
    • PROPAGATION_RNESTED 如果当前存在一个事务,则该方法会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独的提交或回滚。如果当前事务不存在,则和PROPAGATION_REQUIRED一样。

事务是否只读

  • 利用数据库事务的“只读”属性,进行特定优化处理。
  • 设置“只读”,注意数据库厂商的支持。Oracle的“readOnly”不起作用,MySQL的“readOnly”影响查询

事务超时

  • 事务超时是一个定时器,在特定时间内完成,否则回滚。
  • 设计事务的注意点:事务不能运行太长时间,否则占用太久资源

事务回滚

  • 运行期异常才回滚,而检查型异常不会回滚
  • 自定义回滚策略
    • 遇到特定的检查型异常时像运行期异常一样回滚。
    • 遇到特定的异常不回滚,即使是运行期异常。

事务状态

  • 通过事务管理器获得TransactionStatus实例
  • 控制事务回滚或提交时需要应用对应的事务状态

编程式事务管理概述

  • 事务管理器方式 spring事务管理的三个接口
    • 步骤:
      1. 获取事务管理器;创建事务属性对象
      2. 获取事务状态对象;创建JDBC模版对象
      3. 业务数据操作
  • 模版事务的方式(推荐) JdbcTemplate
    • 步骤:
      1. 获取模版对象
      2. 选择事务结果类型
      3. 业务数据操作处理
  • 总结:
    • 需要有效的数据源
    • 创建编程事务管理对象
    • 业务逻辑

声明式事务管理

  • 基于AOP,对方法前后拦截
  • 配置类型:tx拦截器;注解方式
  • 实现方式:
    • tx拦截器 使用XML配置
    • 注解方式

事务管理最佳实践

  • 编程式更精确自定义,声明式更解耦业务
  • 小型,业务少,直观的的用编程式
  • 大型,事务操作量,复杂的用声明式
  • 事务管理器类型
    • 不同数据源用不同的事务管理器
      • 正确选择PlatformTransactionManager实现类
      • 全局事务的选择JtaTransactionManager

参考

  1. Spring事务管理,https://class.imooc.com/course/577

关于我:

linxinzhe,全栈工程师,目前供职于某世界500强银行的金融科技部门(人工智能,区块链)。

GitHub:https://github.com/linxinzhe

欢迎留言讨论,也欢迎关注我~
我也会关注你的哦!