事务是数据库操作的一个逻辑单位,由一系列SQL语句组成。这些操作要么全部执行,要么全部不执行,确保数据的一致性和完整性。事务主要用于处理多步操作的复杂业务逻辑,如银行转账、订单处理等场景。
一、事务的ACID特性
事务必须满足ACID特性,这是事务的核心原则:
1. 原子性(Atomicity)
事务是一个不可分割的工作单位,事务中的所有操作要么全部成功执行,要么全部失败回滚。不会出现部分执行的情况。
例如:银行转账时,从A账户扣款和向B账户存款两个操作必须同时成功或同时失败。
2. 一致性(Consistency)
事务执行前后,数据库从一个一致性状态转换到另一个一致性状态。数据必须满足预设的规则(如约束、触发器等)。
例如:转账前后,A和B两个账户的总金额保持不变。
3. 隔离性(Isolation)
多个事务并发执行时,一个事务的操作不会被其他事务干扰,各个事务之间相互隔离。
MySQL通过隔离级别控制事务之间的可见性,避免并发问题。
4. 持久性(Durability)
事务一旦提交,其对数据库的修改就是永久性的,即使系统崩溃也不会丢失。
MySQL通过将数据写入磁盘实现持久性。
二、事务的操作语句
MySQL中,事务操作主要通过以下语句实现:
1. 开始事务
START TRANSACTION; -- 或 BEGIN;
功能:标记一个事务的开始,之后的SQL语句将作为事务的一部分。
2. 提交事务
COMMIT;
功能:将事务中所有的修改永久保存到数据库中,事务正常结束。
3. 回滚事务
ROLLBACK;
功能:取消事务中所有的修改,恢复到事务开始前的状态,事务异常结束。
4. 保存点
SAVEPOINT 保存点名称; -- 创建保存点 ROLLBACK TO SAVEPOINT 保存点名称; -- 回滚到指定保存点 RELEASE SAVEPOINT 保存点名称; -- 删除保存点
功能:在事务中创建中间点,允许部分回滚而不是回滚整个事务。
示例:完整的事务流程
-- 开始事务 START TRANSACTION; -- 执行操作(例如转账) UPDATE accounts SET balance = balance - 100 WHERE id = 1; -- 账户1扣款 UPDATE accounts SET balance = balance + 100 WHERE id = 2; -- 账户2收款 -- 检查操作是否正确(实际应用中可能有更复杂的判断) -- 如果正确,提交事务 COMMIT; -- 如果出错,回滚事务 -- ROLLBACK;
三、事务的自动提交机制
MySQL默认启用自动提交(AUTOCOMMIT)模式,即每条SQL语句都会被视为一个独立的事务并自动提交。
1. 查看自动提交状态
SELECT @@AUTOCOMMIT; -- 1表示启用,0表示禁用
2. 禁用自动提交
SET AUTOCOMMIT = 0; -- 禁用自动提交,需手动COMMIT或ROLLBACK
3. 注意事项
- 禁用自动提交后,所有SQL语句都属于当前事务,直到执行COMMIT或ROLLBACK
- 执行DDL语句(如CREATE、ALTER、DROP)会自动提交当前事务,不受AUTOCOMMIT设置影响
四、事务的隔离级别
并发事务可能导致的问题包括:脏读、不可重复读、幻读。MySQL通过设置隔离级别解决这些问题。
1. 并发事务的问题
- 脏读(Dirty Read):一个事务读取到另一个未提交事务的修改数据
- 不可重复读(Non-repeatable Read):一个事务中多次读取同一数据,结果不一致(被其他事务修改并提交)
- 幻读(Phantom Read):一个事务中多次查询,结果集的行数不一致(被其他事务插入或删除并提交)
2. MySQL的隔离级别
MySQL支持四种隔离级别(从低到高):
(1)读未提交(READ UNCOMMITTED)
允许读取未提交的事务数据,可能导致脏读、不可重复读、幻读。
性能最高,但安全性最低。
(2)读已提交(READ COMMITTED)
只能读取已提交的事务数据,避免脏读,但可能出现不可重复读、幻读。
是许多数据库的默认隔离级别(如Oracle)。
(3)可重复读(REPEATABLE READ)
保证同一事务中多次读取同一数据的结果一致,避免脏读和不可重复读,但可能出现幻读。
是MySQL InnoDB引擎的默认隔离级别。
(4)串行化(SERIALIZABLE)
最高隔离级别,事务串行执行,避免所有并发问题,但性能最低。
3. 隔离级别的相关操作
查看当前会话的隔离级别 SELECT @@SESSION.TRANSACTION_ISOLATION; 查看全局的隔离级别 SELECT @@GLOBAL.TRANSACTION_ISOLATION; 设置当前会话的隔离级别 SET SESSION TRANSACTION ISOLATION LEVEL 隔离级别名称; 设置全局的隔离级别 SET GLOBAL TRANSACTION ISOLATION LEVEL 隔离级别名称; 示例:设置当前会话为读已提交级别 SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
五、事务的使用场景
事务适用于需要保证多个操作原子性的场景,典型包括:
1. 金融交易:转账、支付等涉及资金变动的操作
2. 订单处理:创建订单、扣减库存、记录交易等组合操作
3. 数据迁移:从一个表移动数据到另一个表,需确保两边数据一致
4. 用户注册:同时创建用户记录、权限记录、初始配置等
六、事务的注意事项
1. 事务应尽可能短,减少锁定资源的时间,提高并发性能
2. 避免在事务中执行不必要的操作,只包含相关的SQL语句
3. 选择合适的隔离级别,平衡安全性和性能需求
4. 注意事务中的锁机制,避免死锁(两个事务互相等待对方释放资源)
5. 确保使用支持事务的存储引擎(如InnoDB),MyISAM引擎不支持事务
6. 事务失败时,使用ROLLBACK而不是手动编写反向操作恢复数据
七、事务与存储引擎
MySQL的事务支持依赖于存储引擎:
InnoDB:支持事务、行级锁、外键等高级特性,是MySQL默认的存储引擎
MyISAM:不支持事务和外键,只支持表级锁,适用于读多写少的场景
MEMORY:数据存储在内存中,不支持事务,重启后数据丢失
因此,使用事务时需确保表使用InnoDB存储引擎。
85万+

被折叠的 条评论
为什么被折叠?



