1. 事务简介
- 事务:一组操作的集合,要么全部执行成功,要么全部回滚,确保数据库的完整性。
- 事务提供了数据的一致性和完整性,常用于多步骤的数据操作中,确保操作的安全和准确。
2. 事务的四大特性(ACID)
- 原子性 (Atomicity):事务中的所有操作是一个不可分割的原子单元,要么全部完成,要么全部不完成。
- 一致性 (Consistency):事务执行前后,数据库必须保持一致状态,不会有半完成状态。
- 隔离性 (Isolation):事务的操作对其他事务不可见,直到事务提交为止。
- 持久性 (Durability):事务一旦提交,其影响是永久的,不会因系统故障而丢失。
3. 事务操作
-
启动事务:
START TRANSACTION; -- 或 BEGIN;
-
提交事务:
COMMIT;
-
回滚事务:
ROLLBACK;
-
设置自动提交:
SET @@autocommit = 0; -- 禁用自动提交
4. 并发事务问题
并发事务可能会带来一些常见的问题,了解这些问题有助于理解隔离级别的作用:
- 脏读 (Dirty Read):一个事务读取了另一个未提交事务的更改,如果该事务回滚,将导致读取到无效数据。
- 不可重复读 (Non-repeatable Read):一个事务在多次读取中,数据被另一个事务修改,导致多次读取结果不一致。
- 幻读 (Phantom Read):一个事务在读取某些数据后,另一个事务插入了新数据,导致前一个事务在后续读取时“幻”出新的数据行。
5. 事务的隔离级别
隔离级别定义了一个事务与其他事务的隔离程度,MySQL 提供四种隔离级别:
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read Uncommitted | √ | √ | √ |
Read Committed | × | √ | √ |
Repeatable Read (默认) | × | × | √ |
Serializable | × | × | × |
- Read Uncommitted:最低的隔离级别,允许脏读。适用于对隔离要求低的情况。
- Read Committed:仅允许读取已提交的数据,避免了脏读,但可能产生不可重复读和幻读。
- Repeatable Read:不允许脏读和不可重复读,但可能出现幻读。MySQL 的默认隔离级别。
- Serializable:最高的隔离级别,完全隔离,防止所有并发问题,但效率最低。
6. 查看和设置事务隔离级别
-
查看当前隔离级别:
SELECT @@TRANSACTION_ISOLATION;
-
设置事务隔离级别:
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- 可选择的级别有 READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE
7. 事务示例代码
以下是一个简单的事务示例,展示了如何使用事务完成一组操作,并如何应对可能的错误。
-- 开始事务
START TRANSACTION;
-- 尝试进行操作
UPDATE accounts SET balance = balance - 100 WHERE user_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE user_id = 2;
-- 检查是否有错误
IF @@ERROR
THEN
-- 回滚事务
ROLLBACK;
ELSE
-- 提交事务
COMMIT;
END IF;