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

MySQL 的事务(Transaction)

1. 什么是事务?​

事务是​​一组原子性的数据库操作序列​​,这些操作要么​​全部执行成功​​,要么​​全部失败回滚​​。事务的目的是确保数据库从一个一致状态转换到另一个一致状态,即使在执行过程中发生错误或中断。

​典型场景​​:银行转账(A 转给 B 100 元)需要两个操作:

  1. A 的账户扣除 100 元。
  2. B 的账户增加 100 元。
    这两个操作必须作为一个整体执行,否则会导致数据不一致。

​2. 事务的 ACID 特性​

事务必须满足 ​​ACID​​ 特性:

特性描述
​原子性​​ (Atomicity)事务中的操作要么全部成功,要么全部失败回滚。
​一致性​​ (Consistency)事务执行后,数据库从一个有效状态转换到另一个有效状态(如数据完整性约束)。
​隔离性​​ (Isolation)并发事务之间互不干扰,每个事务感觉不到其他事务在同时执行。
​持久性​​ (Durability)事务提交后,修改会永久保存到数据库(即使系统崩溃)。

​3. 事务控制语句​

MySQL 通过以下语句管理事务:

  • START TRANSACTION​ 或 ​BEGIN​:开启一个新事务。
  • COMMIT​:提交事务,确认所有修改。
  • ROLLBACK​:回滚事务,撤销所有未提交的修改。
  • SAVEPOINT​:在事务中设置保存点,用于部分回滚。

​示例​​:

START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE user = 'A';
UPDATE accounts SET balance = balance + 100 WHERE user = 'B';
-- 如果两个操作都成功
COMMIT;
-- 如果失败
ROLLBACK;

​4. 事务的隔离级别​

多个事务并发执行时,可能引发以下问题:

问题描述
​脏读​​ (Dirty Read)读取到其他事务未提交的数据。
​不可重复读​​ (Non-Repeatable Read)同一事务内多次读取同一数据,结果不一致(数据被其他事务修改)。
​幻读​​ (Phantom Read)同一事务内多次查询,结果集的行数不同(数据被其他事务新增/删除)。

MySQL 支持 4 种隔离级别(默认:REPEATABLE READ):

隔离级别脏读不可重复读幻读性能
​READ UNCOMMITTED​✔️ 可能✔️ 可能✔️ 可能最高
​READ COMMITTED​❌ 避免✔️ 可能✔️ 可能较高
​REPEATABLE READ​❌ 避免❌ 避免✔️ 可能中等
​SERIALIZABLE​❌ 避免❌ 避免❌ 避免最低

​设置隔离级别​​:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

​5. 事务的锁机制​

MySQL 通过锁保证隔离性,常见的锁类型:

  • ​行锁(Row Lock)​​:锁定某一行(InnoDB 默认)。
  • ​表锁(Table Lock)​​:锁定整张表(MyISAM 默认)。
  • ​间隙锁(Gap Lock)​​:锁定一个范围(防止幻读,在 REPEATABLE READ 级别中使用)。

​示例​​:

  • 事务 A 更新某行时,会对该行加锁,事务 B 必须等待锁释放才能操作。

​6. 事务的实现原理​

  • ​原子性​​:通过 ​​Undo Log​​ 实现回滚操作。
  • ​持久性​​:通过 ​​Redo Log​​ 确保数据持久化(即使崩溃后恢复)。
  • ​隔离性​​:通过 ​​锁机制​​ 和 ​​MVCC(多版本并发控制)​​ 实现。
  • ​一致性​​:由应用层和数据库约束(如主键、外键)共同保证。

​7. 事务的常见应用场景​

  1. 金融交易(转账、扣款)。
  2. 订单系统(创建订单、扣减库存)。
  3. 批量数据操作(保证多个操作原子性)。

​8. 注意事项​

  1. ​避免长事务​​:长时间未提交的事务会占用锁资源,导致性能下降。
  2. ​合理选择隔离级别​​:根据业务需求平衡一致性和性能。
  3. ​监控死锁​​:使用 SHOW ENGINE INNODB STATUS 分析死锁。
  4. ​重试机制​​:事务失败时,应用层应设计重试逻辑。

​9. 示例:银行转账的完整流程​

-- 设置隔离级别为 REPEATABLE READ
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;START TRANSACTION;-- 检查 A 的余额是否足够
SELECT balance INTO @a_balance FROM accounts WHERE user = 'A' FOR UPDATE;IF @a_balance >= 100 THENUPDATE accounts SET balance = balance - 100 WHERE user = 'A';UPDATE accounts SET balance = balance + 100 WHERE user = 'B';COMMIT;
ELSEROLLBACK;
END IF;

相关文章:

  • 使用pyTorch 自然语言处理(NLP)知识库创建
  • 第十七章,反病毒---防病毒网管
  • Ubuntu 第11章 网络管理_常用的网络配置命令
  • AT9880B北斗单模卫星定位SOC芯片
  • 报错 | vitest中,vue中使用jsx语法,报错:ReferenceError: React is not defined
  • Java设计模式之单例模式:从入门到精通
  • 虚假AI工具通过Facebook广告传播新型Noodlophile窃密木马
  • 国产Excel处理控件Spire.XLS系列教程:C# 将Excel文件转换为Markdown格式
  • C++Primerplus编程练习 第六章
  • 数据库故障排查指南
  • PDF文档解析新突破:图表识别、公式还原、手写字体处理,让AI真正读懂复杂文档!
  • 系统间安全复制和同步文件
  • 数据库审计如何维护数据完整性:7 种工具和技术
  • 1.3.2 linux音频PulseAudio详细介绍
  • ubuntu 24.04 error: cannot uninstall blinker 1.7.0, record file not found. hint
  • stm32 debug卡在0x1FFFxxxx
  • 【Unity笔记】PathCreator使用教程:用PathCreator实现自定义轨迹动画与路径控制
  • Spring、SpringMVC、SpringBoot、SpringCloud 联系与区别
  • linux ptrace 图文详解(八) gdb跟踪被调试程序的子线程、子进程
  • 安全核查基线-3.用户umask设置策略
  • 虚假认定实质性重组、高估不良债权价值,原中国华融资产重庆分公司被罚180万元
  • 纽约大学朗格尼医学中心的转型带来哪些启示?
  • A股低开高走全线上涨:军工股再度领涨,两市成交12934亿元
  • 全国首例在沪完成,这项近视治疗手术不到10秒
  • 中方对中美就关税谈判的立场发生变化?外交部:中方立场没有任何改变
  • 过半中国上市公司去年都在“扩编”,哪些公司人效最高