MySQL 事务的四大特性通常用ACID(Atomicity, Consistency, Isolation, Durability)来表示。ACID特性确保了数据库事务的可靠性和数据的一致性。下面详细介绍每一个特性:
1. 原子性 (Atomicity)
原子性指的是事务是一个不可分割的工作单元,事务中的所有操作要么全部成功,要么全部失败回滚。即使在系统崩溃的情况下,也不会有部分成功、部分失败的状态。
- 实现方法:通过日志(如MySQL的Redo Log和Undo Log)记录事务操作。事务提交之前,所有操作的中间状态都可以回滚。
示例
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
如果在上述事务中,第二条 UPDATE
语句失败,则第一条 UPDATE
语句的操作也会被回滚。
2. 一致性 (Consistency)
一致性指的是事务在完成之前和之后,数据库都必须处于一致的状态。数据库从一个一致状态转换到另一个一致状态。事务执行过程中,数据可以是暂时不一致的,但在事务提交时,必须使数据恢复到一致状态。
- 实现方法:通过约束(如外键约束、唯一性约束)和触发器等机制确保数据的一致性。
示例
假设有一个 accounts
表,每个账户的余额不能为负数:
CREATE TABLE accounts (id INT PRIMARY KEY,balance DECIMAL(10, 2) NOT NULL CHECK (balance >= 0)
);
事务:
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
如果第一个更新导致余额为负数,则事务会失败并回滚,保持一致性。
3. 隔离性 (Isolation)
隔离性指的是并发事务之间互不干扰。一个事务的中间状态对其他事务不可见。事务隔离级别决定了事务间的隔离程度,MySQL支持四种隔离级别:
- 读未提交 (READ UNCOMMITTED):最低级别,允许脏读,即一个事务可以读取另一个未提交事务的数据。
- 读已提交 (READ COMMITTED):只允许读取已经提交的数据,防止脏读。
- 可重复读 (REPEATABLE READ):在同一个事务中,多次读取同一数据结果一致,防止不可重复读。在InnoDB中,这是默认隔离级别,且通过多版本并发控制 (MVCC) 防止幻读。
- 序列化 (SERIALIZABLE):最高级别,通过强制事务顺序执行,防止幻读。
示例
设置隔离级别:
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
事务1:
BEGIN;
SELECT balance FROM accounts WHERE id = 1;
-- 在事务2中更新 accounts 表
COMMIT;
事务2:
BEGIN;
UPDATE accounts SET balance = balance + 50 WHERE id = 1;
COMMIT;
在可重复读隔离级别下,事务1在其生命周期内看到的 balance
值不会改变,即使事务2更新了该值。
4. 持久性 (Durability)
持久性指的是事务一旦提交,其对数据库的修改是永久的,即使系统崩溃也不会丢失数据。
- 实现方法:通过将事务日志记录到磁盘确保持久性。在MySQL中,InnoDB存储引擎通过重做日志(Redo Log)实现持久性。
示例
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
在事务提交后,即使系统崩溃,再次重启数据库时,通过重做日志,可以恢复到事务提交后的状态。
总结
ACID特性确保了数据库事务的可靠性和数据的一致性。通过理解和利用这些特性,可以构建更加健壮和可靠的数据库应用程序。