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

事务处理与事务隔离

1. 事务处理

定义:事务是数据库执行过程中的一个逻辑单位,要么全部执行成功,要么全部失败回滚。

1.1. 事务的特性ACID

特性

英文

说明

原子性 A

Atomicity

操作不可分割,要么全部成功要么全部失败。

一致性 C

Consistency

事务前后数据库都处于一致状态,遵循约束(如主键唯一)。

隔离性 I

Isolation

并发事务之间互不干扰,一个事务未提交前对其他事务不可见。

持久性 D

Durability

一旦事务提交,对数据库的更改是永久性的,重启也不会丢失。

  • 一致性注意点:是业务定义的一致状态,和约束规则(如唯一性、外键)密切相关。
  • 持久性保障机制:通过 重做日志(redo log) 实现,确保系统崩溃后仍能恢复已提交事务。

MySQL 中事务的支持依赖存储引擎:

  • InnoDB:支持事务
  • MyISAM:不支持事务
  • 使用 SHOW ENGINES 可查看各引擎是否支持事务。

1.2. 事务控制

事务控制语句

命令

功能

START TRANSACTION / BEGIN

显式开启一个事务

COMMIT

提交事务,使修改永久保存

ROLLBACK

回滚事务,撤销所有未提交的操作

SAVEPOINT savepoint_name

创建保存点

ROLLBACK TO savepoint_name

回滚到某个保存点

RELEASE SAVEPOINT savepoint_name

删除保存点

SET TRANSACTION ISOLATION LEVEL ...

设置事务隔离级别

隐式 vs 显式事务

隐式事务(默认自动提交)

  • autocommit=1:每条 SQL 默认自动提交。

不过这时,如果采用 START TRANSACTION 或者 BEGIN 的方式来显式地开启事务,那么这个事务只有在 COMMIT 时才会生效,在 ROLLBACK 时才会回滚。

显式事务

  • autocommit=0 或使用 START TRANSACTION 开启,需要显式 COMMITROLLBACK
  • 可通过命令设置自动提交:
SET autocommit = 0; -- 关闭自动提交
SET autocommit = 1; -- 开启自动提交

注意:

  • 事务是保持数据一致性的核心机制,尤其在并发和出错场景下至关重要。
  • InnoDB 引擎支持事务,配合日志机制保障数据完整性。
  • 熟练掌握事务控制语句和 MySQL 中事务默认行为,有助于规避数据异常。
  • 注意配置参数(如 autocommit, completion_type)对事务行为的影响。

2. 事务隔离

2.1. 事务并发导致的三种异常现象

异常类型

描述

脏读

读取到其他事务尚未提交的数据。
如读取到他人还未提交的插入或更新。

不可重复读

同一查询在同一事务中读取结果不一致。
如前后两次读取的值不同。

幻读

两次相同条件查询结果集条数不同。
如第二次查询多出新增/修改的数据。

三种异常的区别:

异常类型

定义

涉及的数据变化

何时发生

脏读

读取了其他事务尚未提交的数据

同一条数据,未提交

另一个事务还在进行时

不可重复读

同一事务中两次读取同一记录,内容不同

同一条数据,被提交修改

另一个事务提交后

幻读

同一事务中两次读取满足条件的多条记录,结果条数不同

新增或删除了记录(而非修改)

另一个事务提交后

2.2. 四种事务隔离级别(SQL-92标准)

隔离级别

是否允许脏读

是否允许不可重复读

是否允许幻读

读未提交

✅ 是

✅ 是

✅ 是

读已提交

❌ 否

✅ 是

✅ 是

可重复读

(MySQL 默认)

❌ 否

❌ 否

✅ 是

可串行化(最高)

❌ 否

❌ 否

❌ 否

  • 读未提交(Read Uncommitted):最低隔离级别,效率高,但问题最多。
  • 读已提交(Read Committed):可避免脏读,仍存在不可重复读和幻读。
  • 可重复读(Repeatable Read):避免脏读和不可重复读,但仍可能幻读。
  • 可串行化(Serializable):完全隔离,避免所有异常,但性能最差。
  1. 读未提交,也就是允许读到未提交的数据,这种情况下查询是不会使用锁的,可能会产生脏读、不可重复读、幻读等情况。
  2. 读已提交就是只能读到已经提交的内容,可以避免脏读的产生,属于 RDBMS 中常见的默认隔离级别(比如说 Oracle 和 SQL Server),但如果想要避免不可重复读或者幻读,就需要我们在 SQL 查询的时候编写带加锁的 SQL 语句。
  3. 可重复读,保证一个事务在相同查询条件下两次查询得到的数据结果是一致的,可以避免不可重复读和脏读,但无法避免幻读。MySQL 默认的隔离级别就是可重复读。
  4. 可串行化,将事务进行串行化,也就是在一个队列中按照顺序执行,可串行化是最高级别的隔离等级,可以解决事务读取中所有可能出现的异常情况,但是它牺牲了系统的并发性。

隔离级别越低,意味着系统吞吐量(并发程度)越大,但同时也意味着出现异常问题的可能性会更大。

数据库事务的隔离级别决定了事务之间可以看到对方中间状态的程度。隔离级别越高,系统需要加更多锁或其他机制来避免数据被其他事务“干扰”,因此限制了并发访问的自由度。

在实际使用过程中我们往往需要在性能和正确性上进行权衡和取舍,没有完美的解决方案,只有适合与否。

一个隔离级别的实现满足下面两个条件:

  1. 正确性:只要能满足某一个隔离级别,一定能解决这个隔离级别对应的异常问题。
  2. 与实现无关:实际上 RDBMS 种类很多,这就意味着有多少种 RDBMS,就有多少种的实现方式,因此它们实现隔离级别的原理可能不同,然而一个好的标准不应该限制其实现的方式。

相关文章:

  • 哈希表原理与双散列实战指南
  • HJ14 字符串排序【牛客网】
  • Global Securities Markets第一章知识点总结
  • 【Docker 新手入门指南】第十章:Dockerfile
  • http协议和session会话
  • 恢复二叉搜索树:递归与中序遍历的智慧应用
  • 汇编语言的子程序魔法:解锁四则运算的奥秘
  • AtCoder Beginner Contest 407(ABCDE)
  • 机器学习模型度量指标(混淆矩阵、准确率、精确率、召回率、F1分数、ROC曲线、AUC、平均精度均值)
  • (泛函分析)压缩映射
  • 线性回归原理推导与应用(七):逻辑回归原理与公式推导
  • [yolov11改进系列]使用轻量级骨干网络MobileNetV4替换backbone的python源码+训练源码+改进流程+改进原理
  • S32K3开发问题-ADC采样电压一直为5V原因分析及处理
  • 探索链表的奇妙世界:从基础到高级应用
  • RIP 协议实验全记录:从配置到问题解决
  • Linux常见指令合集+知识点
  • 哪些实验需要强磁场
  • esp32+IDF V5.1.1版本编译freertos报错
  • C++八股 —— 手撕定时器
  • 树形DP
  • wordpress开源博客系统最新版/成都移动seo
  • wordpress只能在局域网/seog
  • 买链接做网站 利润高吗/手机百度下载app
  • 网站怎么添加代码/视频号的网站链接
  • 旅游小镇网站建设方案/友链交易平台
  • 政务公开和网站建设工作问题/网络推广员的工作内容和步骤