事务和隔离级别
[[隔离级别、锁、脏读、不可重复读与幻读问题]]
ACID
- Atomicity(原子性):事务中的所有操作要么全部完成,要么全部不完成
- Consistency(一致性):事务将数据库从一个有效状态转移到另一个有效状态
- Isolation(隔离性):并发事务互不干扰
- Durability(持久性):一旦事务提交,结果永久保存
多条SQL语句需要显式使用事务控制语句(如BEGIN, COMMIT, ROLLBACK)来保证ACID属性,单条SQL不一定能ACID
单条SQL:
原子性(Atomicity)
- 通常满足:单条SQL语句在大多数RDBMS中默认作为隐式事务执行
- 例外情况:
- 批量操作(如INSERT INTO … SELECT)可能部分成功
- 某些数据库的特定语句(如MySQL的ALTER TABLE可能不支持原子DDL)
隔离性(Isolation)
- 受隔离级别影响
持久性(Durability) - 可能不满足的情况:
- 使用内存表(如MySQL的MEMORY引擎)
MySQL 事务详解
事务是数据库管理系统中的一个核心概念,它代表一组必须全部成功或全部失败的数据库操作。MySQL 中的事务主要用于保证数据库操作的完整性和一致性。
一、事务的基本概念
1. 什么是事务?
事务(Transaction)是数据库操作的最小工作单元,是用户定义的一个操作序列,这些操作要么全部执行,要么全部不执行。
2. 事务的典型特性(ACID):
- **原子性(Atomicity)**:事务是不可分割的工作单位,事务中的操作要么全部成功,要么全部失败回滚
- **一致性(Consistency)**:事务执行前后,数据库从一个一致状态变到另一个一致状态
- **隔离性(Isolation)**:多个事务并发执行时,一个事务的执行不应影响其他事务
- **持久性(Durability)**:一旦事务提交,其所做的修改会永久保存在数据库中
二、MySQL 中的事务操作
1. 基本语法
1 | START TRANSACTION;-- 或 BEGIN |
2. 事务控制语句
语句 | 功能 |
---|---|
START TRANSACTION 或 BEGIN |
开始一个新事务 |
COMMIT |
提交当前事务,使更改永久化 |
ROLLBACK |
回滚当前事务,取消所有更改 |
SAVEPOINT identifier |
在事务中创建保存点 |
ROLLBACK TO [SAVEPOINT] identifier |
回滚到指定保存点 |
RELEASE SAVEPOINT identifier |
删除保存点 |
SET TRANSACTION |
设置事务的隔离级别 |
三、事务的隔离级别
MySQL 支持四种隔离级别:
- READ UNCOMMITTED (读未提交)
- 可能读取到其他事务未提交的数据(脏读)
- 性能最好,但一致性最差
- READ COMMITTED (读已提交)
- 只能读取已提交的数据
- 解决脏读问题,但可能出现不可重复读
- REPEATABLE READ (可重复读) - MySQL默认
- 同一事务中多次读取同样数据结果一致
- 解决不可重复读问题,但可能出现幻读
- SERIALIZABLE (串行化)
- 最高隔离级别,完全串行执行
- 解决所有并发问题,但性能最差
设置隔离级别:
1 | SET TRANSACTION ISOLATION LEVEL READ COMMITTED; |
四、事务的实际应用示例
1. 银行转账示例
1 | START TRANSACTION; |
2. 使用保存点(SAVEPOINT)
1 | START TRANSACTION; |
五、事务的注意事项
- 存储引擎支持:
- InnoDB 完全支持事务
- MyISAM 不支持事务
- 自动提交模式:
- MySQL 默认是自动提交(autocommit=1)
- 可以关闭自动提交:
SET autocommit=0;
- 长事务问题:
- 避免长时间运行的事务,会锁定资源
- 大事务可以拆分为小事务
- 死锁处理:
- MySQL 能检测死锁并自动回滚其中一个事务
- 应用层应实现重试机制
六、事务的最佳实践
- 尽量使事务简短,减少锁定时间
- 避免在事务中进行用户交互
- 合理设置隔离级别,平衡一致性和性能
- 处理事务失败情况,实现重试逻辑
- 监控长事务和死锁情况
通过正确使用事务,可以确保数据库操作的安全性和一致性,特别是在处理金融交易、订单处理等关键业务场景时尤为重要。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Min的博客!
评论