事务Transaction

article/2025/8/20 8:19:50

事务(Transaction)是数据库管理系统中的一个重要概念,它是一组操作的集合,这些操作要么全部成功,要么全部失败,以确保数据的完整性和一致性。

一、事务的特性(ACID)

  1. 原子性(Atomicity)

    • 原子性是指事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败。例如,在一个银行转账的事务中,从账户A向账户B转账100元,这个事务包括两个操作:从账户A减去100元和向账户B加上100元。如果在执行过程中,账户A已经减去了100元,但由于网络故障等原因,账户B没有加上100元,那么这个事务就会失败,系统会回滚到事务开始之前的状态,账户A的钱不会被扣除。

  2. 一致性(Consistency)

    • 一致性是指事务执行前后,数据库的完整性约束没有被破坏。它保证了事务的执行使数据库从一个一致的状态转换到另一个一致的状态。例如,在一个订单管理系统中,订单表和订单明细表之间存在外键约束。如果事务试图插入一个不存在的订单编号到订单明细表中,那么这个事务就会违反一致性约束,事务会失败。

  3. 隔离性(Isolation)

    • 隔离性是指多个事务并发执行时,一个事务的执行不应受到其他事务的干扰。数据库系统提供了不同的隔离级别来控制事务之间的隔离程度。常见的隔离级别有:

      • 读未提交(Read Uncommitted):最低的隔离级别,一个事务可以读取到其他事务未提交的数据。这可能会导致脏读(读取到其他事务尚未提交的错误数据)。

      • 读已提交(Read Committed):一个事务只能读取到其他事务已经提交的数据,避免了脏读,但可能会出现不可重复读(在同一个事务中,多次读取同一数据得到的结果不同)。

      • 可重复读(Repeatable Read):保证在同一个事务中,多次读取同一数据的结果是一致的,避免了不可重复读,但可能会出现幻读(事务A读取到的某几行数据在事务B的插入操作下,再次读取时出现了新的数据行)。

      • 可串行化(Serializable):最高的隔离级别,事务串行执行,避免了脏读、不可重复读和幻读,但并发性能较差。

  4. 持久性(Durability)

    • 持久性是指事务一旦提交,对数据库的改变就是永久的,即使系统出现故障也不会丢失。例如,当一个事务提交后,即使数据库服务器突然断电,再次启动后,事务所做的一切改变仍然会被保留。

二、事务的控制语句

在关系型数据库(如MySQL、PostgreSQL等)中,事务的控制语句主要包括以下几个:

  1. 开启事务

    • 在MySQL中,可以通过START TRANSACTIONBEGIN语句开启一个事务。

  2. 提交事务

    • 当事务中的所有操作都执行成功后,可以通过COMMIT语句提交事务,使事务中的所有操作永久生效。

  3. 回滚事务

    • 如果事务中的某个操作失败,可以通过ROLLBACK语句回滚事务,撤销事务中已经执行的操作,使数据库恢复到事务开始之前的状态。

  4. 设置保存点

    • 在事务中,可以使用SAVEPOINT语句设置保存点,以便在需要时可以回滚到某个保存点。

    • 如果需要回滚到某个保存点,可以使用ROLLBACK TO语句。

三、事务的应用场景

  1. 金融领域

    • 在银行转账、股票交易等金融业务中,事务的使用至关重要。例如,当用户A向用户B转账时,需要确保从用户A的账户中扣除相应的金额,并且将相同的金额添加到用户B的账户中。如果其中一个操作失败,整个事务就会回滚,避免了资金的错误转移。

  2. 电子商务领域

    • 在电商平台的订单处理过程中,事务可以确保订单的创建、库存的更新和支付状态的更新等操作的原子性和一致性。例如,当用户下单时,需要检查库存是否充足,如果库存不足,则整个订单创建事务会失败,避免了超卖的情况。

  3. 医疗信息系统

    • 在医疗信息系统的患者病历更新、药品库存管理等操作中,事务可以保证数据的完整性和一致性。例如,当医生为患者更新病历时,需要确保所有的检查结果、诊断信息等都正确更新,如果其中一个操作失败,整个事务会回滚,避免了病历信息的错误。

Spring框架@Transaction注释

在Spring框架里,我们通过@Transaction注释,实现事务管理,当然底层实现还是基于数据库事务的。

事务传播行为定义了当一个事务方法被另一个事务方法调用时,事务如何传播。Spring提供了多种传播行为,每种行为都有不同的事务处理方式。

事务隔离级别定义了多个事务并发执行时的隔离程度。

事务回滚规则定义了在哪些异常情况下事务会被回滚。

这种就是最简单的@Transaction注释用法

使用的是默认配置:

  • 传播行为:REQUIRED(默认)
  • 隔离级别:DEFAULT(使用数据库默认隔离级别)
  • 回滚规则:默认只对RuntimeException和Error进行回滚

一、事务传播行为(Propagation Behavior)

Propagation 传播

@Transactional(propagation = Propagation.REQUIRED)

事务传播行为定义了当一个事务方法被另一个事务方法调用时,事务如何传播。Spring提供了多种传播行为,每种行为都有不同的事务处理方式。

1. REQUIRED(默认)
  • 描述:如果当前存在事务,则加入该事务;如果当前没有事务,则开启一个新的事务。

  • 场景:这是最常用的传播行为。适用于大多数业务场景,确保方法调用时始终在事务上下文中执行。

  • 例子

    @Transactional(propagation = Propagation.REQUIRED)
    public void methodA() {// 调用methodBmethodB();
    }@Transactional(propagation = Propagation.REQUIRED)
    public void methodB() {// 业务逻辑
    }
    • methodA被调用,然后里面的methodB被调用。这时候A是外部事物,B是内部事务,例子里,A有Transactional有事务,就是B的外部存在事务A,所以B融入到A的事务里。

    • 如果A没有事务,B就新建事务

2. SUPPORTS
  • 描述:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。

  • 场景:适用于那些不需要事务,但可以加入现有事务的场景。

  • 例子

    @Transactional(propagation = Propagation.REQUIRED)
    public void methodA() {// 调用methodBmethodB();
    }@Transactional(propagation = Propagation.SUPPORTS)
    public void methodB() {// 业务逻辑
    }
    • 如果methodA中存在事务,则methodB会加入到这个事务中。

    • 如果methodA中没有事务,则methodB会以非事务方式执行。

3. MANDATORY
  • 描述:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

  • 场景:适用于那些必须在事务上下文中执行的场景。

  • 例子

    @Transactional(propagation = Propagation.REQUIRED)
    public void methodA() {// 调用methodBmethodB();
    }@Transactional(propagation = Propagation.MANDATORY)
    public void methodB() {// 业务逻辑
    }
    • 如果methodA中存在事务,则methodB会加入到这个事务中。

    • 如果methodA中没有事务,则会抛出TransactionRequiredException

4. REQUIRES_NEW
  • 描述:开启一个新的事务,如果当前存在事务,则暂停当前事务。

  • 场景:适用于那些需要独立事务的场景,例如在日志记录或审计操作中。

  • 例子

    @Transactional(propagation = Propagation.REQUIRED)
    public void methodA() {// 调用methodBmethodB();
    }@Transactional(propagation = Propagation.REQUIRES_NEW)
    public void methodB() {// 业务逻辑
    }
    • 如果methodA中存在事务,则methodB会开启一个新的事务,methodA的事务会被暂停。

    • 如果methodA中没有事务,则methodB会开启一个新的事务。

5. NOT_SUPPORTED
  • 描述:以非事务方式执行,如果当前存在事务,则暂停当前事务。

  • 场景:适用于那些不需要事务的场景,例如读取配置文件等。

  • 例子

    @Transactional(propagation = Propagation.REQUIRED)
    public void methodA() {// 调用methodBmethodB();
    }@Transactional(propagation = Propagation.NOT_SUPPORTED)
    public void methodB() {// 业务逻辑
    }
    • 如果methodA中存在事务,则methodB会以非事务方式执行,methodA的事务会被暂停。

    • 如果methodA中没有事务,则methodB会以非事务方式执行。

6. NEVER
  • 描述:以非事务方式执行,如果当前存在事务,则抛出异常。

  • 场景:适用于那些绝对不能在事务上下文中执行的场景。

  • 例子

    @Transactional(propagation = Propagation.REQUIRED)
    public void methodA() {// 调用methodBmethodB();
    }@Transactional(propagation = Propagation.NEVER)
    public void methodB() {// 业务逻辑
    }
    • 如果methodA中存在事务,则会抛出IllegalTransactionStateException

    • 如果methodA中没有事务,则methodB会以非事务方式执行。

7. NESTED
  • 描述:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则开启一个新的事务。

  • 场景:适用于需要嵌套事务的场景,例如在复杂的业务流程中。

  • 例子

    @Transactional(propagation = Propagation.REQUIRED)
    public void methodA() {// 调用methodBmethodB();
    }@Transactional(propagation = Propagation.NESTED)
    public void methodB() {// 业务逻辑
    }
    • 如果methodA中存在事务,则methodB会开启一个嵌套事务。

    • 如果methodA中没有事务,则methodB会开启一个新的事务。


二、事务隔离级别(Isolation Level)

Isolation 隔离

@Transactional(isolation = Isolation.READ_UNCOMMITTED)

事务隔离级别定义了多个事务并发执行时的隔离程度。Spring支持以下几种隔离级别:

1. DEFAULT
  • 描述:使用数据库默认的隔离级别(通常是READ_COMMITTED)。

  • 场景:适用于大多数场景,不需要显式指定隔离级别。

2. READ_UNCOMMITTED
  • 描述:允许读取未提交的数据,可能会导致脏读。

  • 场景:适用于对数据一致性要求不高的场景。

  • 例子

    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
    public void methodA() {// 业务逻辑
    }
3. READ_COMMITTED
  • 描述:只能读取已提交的数据,避免了脏读,但可能会出现不可重复读。

  • 场景:适用于大多数场景,避免了脏读。

  • 例子

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void methodA() {// 业务逻辑
    }
4. REPEATABLE_READ
  • 描述:保证在同一个事务中,多次读取同一数据的结果是一致的,避免了不可重复读,但可能会出现幻读。

  • 场景:适用于对数据一致性要求较高的场景。

  • 例子

    @Transactional(isolation = Isolation.REPEATABLE_READ)
    public void methodA() {// 业务逻辑
    }
5. SERIALIZABLE
  • 描述:最高的隔离级别,事务串行执行,避免了脏读、不可重复读和幻读,但并发性能较差。

  • 场景:适用于对数据一致性要求极高的场景,但会牺牲性能。

  • 例子

    @Transactional(isolation = Isolation.SERIALIZABLE)
    public void methodA() {// 业务逻辑
    }

三、事务回滚规则(Rollback Rules)

Rollback 反转、卷回

@Transactional(rollbackFor = Exception.class)

事务回滚规则定义了在哪些异常情况下事务会被回滚。默认情况下,Spring事务只会在运行时异常(RuntimeException)时回滚。如果需要在其他类型的异常时也回滚事务,可以在@Transactional注解中指定rollbackFor属性。

1. 默认回滚规则
  • 描述:默认情况下,Spring事务只会在运行时异常(RuntimeException)时回滚。

  • 例子

    @Transactional
    public void methodA() {// 业务逻辑throw new RuntimeException("Error occurred");
    }
    • 如果抛出RuntimeException,事务会被回滚。

2. 自定义回滚规则
  • 描述:可以通过rollbackFor属性指定哪些异常会导致事务回滚。

  • 例子

    @Transactional(rollbackFor = Exception.class)
    public void methodA() {// 业务逻辑throw new Exception("Error occurred");
    }
    • 如果抛出Exception,事务会被回滚。

3. 排除某些异常
  • 描述:可以通过noRollbackFor属性指定哪些异常不会导致事务回滚。

  • 例子

    @

http://www.hkcw.cn/article/cpdOSGLRig.shtml

相关文章

RPG改进1.轻击与重击的搭配与连续释放

这一篇做不做都可以,后面视频作者会做的 就比如,当玩家想abaaba/aabaab/ababaa/abababab/aaaba/baabaa等搭配的释放时,可以进行改进。 1.创建动画通知 2.打开攻击的蒙太奇,添加动画通知 3.打开LightAttackMaster,添加变量 4.打开…

MySQL 索引和事务

目录 一:MySQL 索引介绍 1:索引概述 2:索引作用 3:索引的分类 (1)普通索引 (2)唯一索引 (3)主键索引 (4)组合索引&#xff08…

MySQL 数据库操作

目录 一. MySQL 数据库介绍 二. MySQL 库操作 1.系统数据库 2.数据库操作 三. MySQL 表操作 1.表介绍 2.查看表 3.创建表 4.查看表结构 5.修改表 6.复制和删除 四. MySQL 数据操作 1.插入数据 INSERT 2.删除与更新 INSERT 4.查询数据 INSERT 单表查询 1.单表…

郑州首店停工?胖东来方面回应 工程正常对接中

随着于东来此前公布的胖东来郑州首店开业日期(2026年元旦)临近,网友愈发关注该超市的动态。近日,有网友发现该店的建设似乎停工了。跟不久前热热闹闹的地面部分施工现场相比,如今很难见到工人师傅的身影,甚至“中建七局”几个大字已被拆除。这让网友们开始担忧是否能按计…

女子穿高跟鞋跑步摔伤起诉健身房 责任划分引争议

女子穿高跟鞋跑步摔伤起诉健身房 责任划分引争议!一名女子穿着高跟鞋在健身房跑步机上跑步,不久后因跟不上跑步机速度而摔倒,导致十级伤残。她随后起诉健身房要求赔偿。然而,健身房跑步机旁的墙上贴有不能穿高跟鞋跑步的提醒。2024年3月8日,刘娜(化名)穿着高跟鞋进入益阳…

减肥走回家时家人会在路上迎接我

减肥走回家时家人会在路上迎接我。责任编辑:zx0002

沃尔沃高管谈汽车安全:不抢风头,只想多救一命

沃尔沃高管谈汽车安全。4月15日晚,全新一代沃尔沃XC90正式上线,限时尊享价从47.9万元起跳。这台顶着“旗舰SUV”光环的北欧大块头,不但没来啥夸张参数堆料,也没整那些炫酷得让人眼花缭乱的智能化噱头——它依然稳稳地押注在“安全”两个字上,用最不招摇的方式稳扎传统豪华…

主持人李彬因长期服药满头白发面部浮肿,却依旧保持乐观

5月29日,知名主持人李彬罕见露面发视频,视频中李彬满头白发声音沙哑向大家问好。此前,李彬曾自曝生病,需长期服用药物导致面部浮肿,却依旧保持乐观。李彬,出生于河北省衡水市,中国影视演员、主持人,曾主持《超级大赢家》。责任编辑:zx0002

.NET WinForm图像识别二维码/条形码并读取其中内容

需求:图像识别出一张图片中的二维码或者条形码,并读取其中内容。 一、安装库(特别注意,网上很多都没说清楚) 如果是基于.net framework,则安装ZXing.Net(建议0.14.0版本左右,具体看实际,版本太高,部分接口…

Java 注解与反射(超详细!!!)

Java 注解与反射(超详细!!!) 文章目录 Java 注解与反射(超详细!!!)1.注解1.1内置注解1.1.1 SuppressWarnings注解用法 1.2 元注解1.3自定义注解 2.反射2.1 反…

开关电源输出噪声--陶瓷 电解电容差异

对于LED恒流源驱动,输出只用电解电容,噪声大 对于LED恒流源驱动,输出用电解电容和陶瓷电容(C77& C78改成22uf陶瓷电容),噪声小到50 mV左右

【运维实战】定时任务-crontab命令

定时任务的应用场景 数据备份 定期对重要数据进行备份,是保障数据安全的重要手段。比如,我们可以设置每周日凌晨对整个数据库进行全量备份,或者每天对关键业务数据进行增量备份。这样,即便遇到硬件故障、误操作等意外情况&#…

[免费]SpringBoot+Vue垃圾分类管理【论文+源码+SQL脚本】

大家好,我是java1234_小锋老师,看到一个不错的SpringBootVue垃圾分类管理【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】SpringbootVue垃圾分类管理系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 本论文主要论述了如何使用JAVA语言…

等保测评-Linux主机测评篇

Linux主机测评 目录 Linux主机测评 0x01 前言 0x02 测评过程 1.身份的鉴别 a).对登陆的用户进行身份鉴别和标识,身份标识具有唯一性 b).应具有登录次数限制,登陆超时等措施 c).在进行远程控制中,防止传输过程被窃听 2.访问控制 a).…

面向对象基本概念:多态;附带应用例子

目录 一. 多态的概念简介 二. 多态的例子一:偏好过滤器 三. 多态的例子二:审查描述符(需要元编程知识) 四. 总结 面向对象编程(Object Oriented Programming,OOP)有三大核心概念:封装,继承,多态。前两个…

Linux 串口连接乱码

用到的全部软件,都放在这个网盘里面了,自取。 链接: https://pan.baidu.com/s/1AR6Lj8FS7bokMR5IrLmsIw?pwd3dzv 提取码: 3dzv 如果链接失效了,关注公号:每日早参,回复:资源,即可免费获取&…

linux之web实战rsync

一、rsync简介 rsync是用于数据备份共享以及增量同步的工具,它可以在本地计算机与远程计算机之间,或者两个本地目录之间同步文件(但不支持两台远程计算机之间的同步)。它也可以当作文件复制工具,替代cp和mv命令 二、…

链表经典题目(力扣 easy)

全部题目来自力扣,这里只做学习的记录,内容中部分为AI生成,有不对的地方可以评论或者私信哦~~ 203. 移除链表元素 (版本一)虚拟头节点法 # Definition for singly-linked list. # class ListNode: # def __init_…

UFSH2024 程序化生成 笔记

这篇只是把里面涉及到的网站连接做个记录。有些网站“藏"得太深了。找了半天才找到相关连接 官方视频: [UFSH2024]关于程序化生成,我们还能做什么? | 周杰 徐凯鸣 腾讯IEG Global_哔哩哔哩_bilibili 官方案例资源连接: Vit…

openEuler安装MySql8(tar包模式)

操作系统版本: openEuler release 22.03 (LTS-SP4) MySql版本: 下载地址: https://dev.mysql.com/downloads/mysql/ 准备安装: 上传安装包: 把下载下来的安装包上传到服务器:/opt/software/mysql目录…