当前位置: 首页 > news >正文

Spring事务(Transaction)

事务(Transaction)是基于关系型数据库(RDBMS)的企业应用的重要组成部分。在软件开发领域,事务扮演者十分重要的角色,用来确保应用程序数据的完整性和一致性

事务具有 4 个特性:原子性、一致性、隔离性和持久性,简称为 ACID 特性。
原子性(Atomicity):一个事务是一个不可分割的工作单位,事务中包括的动作要么都做要么都不做。
一致性(Consistency):事务必须保证数据库从一个一致性状态变到另一个一致性状态,一致性和原子性是密切相关的。
隔离性(Isolation):一个事务的执行不能被其它事务干扰,即一个事务内部的操作及使用的数据对并发的其它事务是隔离的,并发执行的各个事务之间不能互相打扰。
持久性(Durability):持久性也称为永久性,指一个事务一旦提交,它对数据库中数据的改变就是永久性的,后面的其它操作和故障都不应该对其有任何影响。

事务允许我们将几个或一组操作组合成一个要么全部成功、要么全部失败的工作单元。如果事务中的所有的操作都执行成功,那自然万事大吉。但如果事务中的任何一个操作失败,那么事务中所有的操作都会被回滚,已经执行成功操作也会被完全清除干净,就好像什么事都没有发生一样。

在现实世界中,最常见的与事务相关的例子可能就是银行转账了。假设我们需要将 1000 元从 A 账户中转到 B 账户中,这个转账操作共涉及了以下两个操作。
从 A 账户中扣除 1000 元;
往 B 账户中存入 1000 元。

如果 A 账户成功地扣除了 1000 元,但向 B 账户存入时失败的话,那么我们将凭空损失 1000 元;如果 A 账户扣款时失败,但却成功地向 B 账户存入 1000 元的话,我们的账户就凭空多出了 1000 元,那么银行就会遭受损失。因此我们必须保证事务中的所有操作要么全部成功,要么全部失败,理解了这一点,我们也就抓住了事务的核心。

作为一款优秀的开源框架和应用平台,Spring 也对事务提供了很好的支持。Spring 借助 IoC 容器强大的配置能力,为事务提供了丰富的功能支持。

事务管理方式

Spring 支持以下 2 种事务管理方式。
在这里插入图片描述
选择编程式事务还是声明式事务,很大程度上就是在控制权细粒度和易用性之间进行权衡。

  • 编程式对事物控制的细粒度更高,我们能够精确的控制事务的边界,事务的开始和结束完全取决于我们的需求,但这种方式存在一个致命的缺点,那就是事务规则与业务代码耦合度高,难以维护,因此我们很少使用这种方式对事务进行管理。
  • 声明式事务易用性更高,对业务代码没有侵入性,耦合度低,易于维护,因此这种方式也是我们最常用的事务管理方式。

Spring 的声明式事务管理主要通过以下 2 种方式实现:

基于 XML 方式的声明式事务管理
基于注解方式的声明式事务管理

事务管理器

Spring 并不会直接管理事务,而是通过事务管理器对事务进行管理的。

在 Spring 中提供了一个 org.springframework.transaction.PlatformTransactionManager 接口,这个接口被称为 Spring 的事务管理器,其源码如下。

public interface PlatformTransactionManager extends TransactionManager {
    TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
    void commit(TransactionStatus status) throws TransactionException;
    void rollback(TransactionStatus status) throws TransactionException;
}

该接口中各方法说明如下:
在这里插入图片描述
这些事务管理器的使用方式十分简单,我们只要根据持久化框架(或平台)选用相应的事务管理器实现,即可实现对事物的管理,而不必关心实际事务实现到底是什么。

TransactionDefinition 接口

Spring 将 XML 配置中的事务信息封装到对象 TransactionDefinition 中,然后通过事务管理器的 getTransaction() 方法获得事务的状态(TransactionStatus),并对事务进行下一步的操作。

TransactionDefinition 接口提供了获取事务相关信息的方法,接口定义如下。

public interface TransactionDefinition {
    int getPropagationBehavior();
    int getIsolationLevel();
    String getName();
    int getTimeout();
    boolean isReadOnly();
}

该接口中方法说明如下。
在这里插入图片描述
事务的隔离级别

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

在实际应用中,经常会出现多个事务同时对同一数据执行不同操作,来实现各自的任务的情况。此时就有可能导致脏读、幻读以及不可重复读等问题的出现。

在理想情况下,事务之间是完全隔离的,这自然不会出现上述问题。但完全的事务隔离会导致性能问题,而且并不是所有的应用都需要事务的完全隔离,因此有时应用程序在事务隔离上也有一定的灵活性。

Spring 中提供了以下隔离级别,我们可以根据自身的需求自行选择合适的隔离级别。
在这里插入图片描述
关于事务隔离级别、脏读、幻读、不可重复度等概念的详细介绍,请阅读《数据库事务隔离级别》一节。

事务的传播行为

事务传播行为(propagation behavior)指的是,当一个事务方法被另一个事务方法调用时,这个事务方法应该如何运行。例如,事务方法 A 在调用事务方法 B 时,B 方法是继续在调用者 A 方法的事务中运行呢,还是为自己开启一个新事务运行,这就是由事务方法 B 的事务传播行为决定的。

事务方法指的是能让数据库表数据发生改变的方法,例如新增数据、删除数据、修改数据的方法。

Spring 提供了以下 7 种不同的事务传播行为。
在这里插入图片描述
TransactionStatus 接口

TransactionStatus 接口提供了一些简单的方法,来控制事务的执行、查询事务的状态,接口定义如下。

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

该接口中各方法说明如下。
在这里插入图片描述

转自:Spring事务(Transaction)_洛卡JAVA架构师的博客-CSDN博客_spring事务

相关文章:

  • Ajax-hook 原理解析
  • JavaScript Array 对象
  • SOCKET句柄泄露带来的内存灾难
  • 浪潮服务器安装Windows Server 2008 R2蓝屏
  • Linux服务器安装Windows虚拟机
  • AD域的详细介绍
  • 网络连接的三种模式:桥接模式,NAT模式,仅主机模式
  • 蓝牙怎么区分单模和双模_双十二无线外设怎么选,手把手教你选购无线外设圆梦无线桌面...
  • 学习5g通信心得体会_从IoT到5G I-IoT:下一代基于IoT的智能算法和5G技术
  • c++大作业迷宫游戏 规定时间内完成_小学生做作业磨蹭的7个原因及对策(老师转给家长)...
  • pyqt联动多层级下拉框_pyqt5-下拉框联动效果
  • python人工智能 动漫生成_使用Python来看看动漫中的你
  • 形容等待时间长的句子_形容“等待时间长”的成语有哪些?
  • ueditor统计字数中文_百度UEditor修改右下角统计字数包含html样式
  • gan怎么输入一维数据_GAN生成图像综述
  • 【159天】尚学堂高琪Java300集视频精华笔记(128)
  • Docker下部署自己的LNMP工作环境
  • interface和setter,getter
  • JavaScript实现分页效果
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • MySQL用户中的%到底包不包括localhost?
  • Object.assign方法不能实现深复制
  • Otto开发初探——微服务依赖管理新利器
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • Python实现BT种子转化为磁力链接【实战】
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • 百度小程序遇到的问题
  • 为视图添加丝滑的水波纹
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • 阿里云重庆大学大数据训练营落地分享
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ​中南建设2022年半年报“韧”字当头,经营性现金流持续为正​
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #QT(串口助手-界面)
  • #每日一题合集#牛客JZ23-JZ33
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
  • (备忘)Java Map 遍历
  • (离散数学)逻辑连接词
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (十八)SpringBoot之发送QQ邮件
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • .net core开源商城系统源码,支持可视化布局小程序
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .net 托管代码与非托管代码
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • @transaction 提交事务_【读源码】剖析TCCTransaction事务提交实现细节
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [C++]C++入门--引用
  • [C++数据结构](22)哈希表与unordered_set,unordered_map实现
  • [CareerCup] 2.1 Remove Duplicates from Unsorted List 移除无序链表中的重复项