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

数据库中的事务

1.基本概念

MySQL 中的事务(Transaction)是一组原子性的 SQL 操作,要么全部执行成功,要么全部失败回滚,保证数据库从一个一致状态转换到另一个一致状态。

简单来说,就是把一组sql语句打包成一个整体,要么全部成功,要么全部失败。
 

2.事务的 ACID 特性

事务的 ACID 特性 是数据库管理系统(DBMS)中事务处理的四个核心原则,确保事务的可靠性和数据的一致性。

它们分别是原子性(A – Atomicity)、一致性(C – Consistency)、隔离性(I – Isolation)、持久性(D – Durability)。

特性描述
原子性事务中的所有操作要么全部成功,要么全部失败回滚。
一致性事务执行前后,数据库必须保持逻辑一致(如约束、外键、触发器等)。
隔离性多个并发事务的执行互不干扰,彼此隔离。
持久性事务提交后,对数据库的修改是永久性的,即使系统崩溃也不丢失。

3.事物的隔离级别

MySQL 支持四种隔离级别(默认是 可重复读(REPEATABLE READ)):

隔离级别解决的问题可能的问题并发性
读未提交READ UNCOMMITTED脏读、不可重复读、幻读最高
读已提交READ COMMITTED脏读不可重复读、幻读次高
可重复读REPEATABLE READ脏读、不可重复读幻读(InnoDB 通过间隙锁避免幻读)次低
串行化SERIALIZABLE所有问题性能低(通过锁表实现)最低

 查看和设置隔离级别:

-- 查看当前隔离级别
SELECT @@transaction_isolation;

-- 设置会话隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

4.不同隔离级别下可能出现的问题:

在数据库事务中,隔离级别(Isolation Level) 决定了事务之间的可见性和影响程度。不同的隔离级别可以防止不同的问题,但也会带来性能或并发性的权衡。以下是不同隔离级别下可能出现的问题:

(1)读未提交和脏读

  • 脏读(Dirty Read):事务可以读取其他事务尚未提交的数据。

    • 示例:事务A修改了某行数据但未提交,事务B读取到了这个未提交的修改。如果事务A回滚,事务B读到的就是无效数据。

读未提交的适用场景
几乎不使用,除非对数据一致性要求极低且追求最高并发性能。

(2)读已提交和不可重复读

  • 不可重复读(Non-Repeatable Read):同一事务内多次读取同一数据,结果可能不同(因为其他事务已提交修改)。

    • 示例:事务A第一次读取某行数据,事务B修改并提交该行数据后,事务A再次读取时发现数据变了。

读已提交的适用场景
适用于大多数OLTP(在线事务处理)系统,如PostgreSQL的默认隔离级别。

(3)可重复读和幻读

  • 幻读(Phantom Read):同一事务内多次执行相同查询,返回的行数可能不同(其他事务插入或删除了数据)。

    • 示例:事务A查询age > 18的用户,事务B插入一条age=20的记录并提交,事务A再次查询时发现多了一条记录。

MySQL的优化
InnoDB引擎REPEATABLE READ下使用间隙锁(Gap Lock) 防止幻读,因此MySQL的REPEATABLE READ实际上可以避免幻读。

也可以说Innodb是使用了Next-Key Lock(临键锁) 来解决幻读的问题,因为间隙锁(Gap Lock)临键锁(Next-Key Lock)的一部分。

可重复读的适用场景
适用于需要事务内数据一致性的场景,如MySQL的默认隔离级别。

(4)串行化

隔离级别为串行化时,基本可以说是百分百安全,安全问题得到了大幅度解决,但是相应的也出现了一些问题:

  • 性能下降:所有事务串行执行,导致并发性能极低。

  • 锁争用严重:大量读写操作会互相阻塞。

串行化的适用场景
仅适用于严格要求数据绝对一致且并发量低的场景,如金融交易系统。

(5)总结

问题总结

隔离级别脏读不可重复读幻读性能影响

读未提交

Read Uncommitted

❌ 可能❌ 可能❌ 可能⚡ 最高

读已提交

Read Committed

✅ 防止❌ 可能❌ 可能⚡⚡ 高

可重复读

Repeatable Read

✅ 防止✅ 防止❌ 可能(但MySQL用间隙锁避免)⚡⚡⚡ 中等

串行化

Serializable

✅ 防止✅ 防止✅ 防止⚡⚡⚡⚡ 最低

5.不可重复读和幻读的区别?

无论是不可重复读还是幻读,本质上都是两次查询的结果不一致,那么他们有什么区别呢?

不可重复读vs幻读:

对比项不可重复读(Non-Repeatable Read)幻读(Phantom Read)
定义同一事务内,多次读取同一行数据,结果不同(数据被其他事务修改)。同一事务内,多次执行相同查询,返回的行数不同(其他事务插入或删除了数据)。
关键区别针对已存在的数据行(值被修改)。针对结果集的行数变化(新增或删除数据)。
隔离级别发生在读已提交,可重复读可以避免可重复读默认仍可能出现(但InnoDB通过Next-Key Lock避免)。
示例事务A读取age=20,事务B将age改为25并提交,事务A再次读取发现值变了。事务A查询age > 20返回2条数据,事务B插入一条age=30并提交,事务A再次查询返回3条数据。
InnoDB解决方案使用行锁(Record Lock) 锁定已读取的行。使用临键锁(Next-Key Lock) 锁定记录和间隙,防止插入新数据。
影响数据值不一致,可能导致逻辑错误。数据集合不一致,影响统计或范围查询结果。

总的来说, 不可重复读和幻读的区别主要是:

  • 不可重复读同一行数据被修改 → 值变化。发生在读已提交

  • 幻读:查询结果集的行数变化 → 新增或删除数据。发生在可重复读

  • InnoDB的优化:在REPEATABLE READ下,通过Next-Key Lock同时解决两者。

 

http://www.dtcms.com/a/121781.html

相关文章:

  • 柑橘病虫害图像分类数据集OrangeFruitDaatset-8600
  • 开发一个环保回收小程序需要哪些功能?环保回收小程序
  • Java程序的基本规则
  • PS教学记录
  • Java 常用安全框架的 授权模型 对比分析,涵盖 RBAC、ABAC、ACL、基于权限/角色 等模型,结合框架实现方式、适用场景和优缺点进行详细说明
  • 信用卡欺诈检测实战教程:从数据预处理到模型优化全解析
  • 什么是声波,声波的传播距离受哪些因素影响?
  • 【RL系列】StepFun之Open-Reasoner-Zero
  • 机器学习 Day09 KNN算法
  • 大数据专业学习路线
  • 某团某点评mtgsig1.2 H5guard加密算法剖析
  • 深入解析Java中的栈:从JVM原理到开发实践
  • 基于IDEA+SpringBoot+Mave+Thymeleaf的系统实现
  • 量子计算入门:开启未来计算的次元之门
  • 华为数字芯片机考2025合集4已校正
  • 【安卓】APP生成器v1.0,生成属于你的专属应用
  • FRP练手:hello,world实现
  • JavaScript的可选链操作符 ?.
  • 【WPF】IOC控制反转的应用:弹窗但不互相调用ViewModel
  • 构建实时、融合的湖仓一体数据分析平台:基于 Delta Lake 与 Apache Iceberg
  • 基于机器视觉的多孔零件边缘缺陷检测(源码C++、opencv、凸包、凸缺陷检测)
  • eplan许可证的用户权限管理
  • 4.实战篇-延迟约束
  • 基于MCP协议调用的大模型agent开发02
  • 11. 盛最多水的容器
  • Linux系统之rm命令的基本使用
  • leetcode每日一题:子数组异或查询
  • 主键索引和唯一索引的区别
  • linux安装mysql常出现的问题
  • 【Linux】进程信号(下)