MySQL(12) 什么是ACID特性?

ACID 是事务处理系统的四个关键特性,用于确保数据库的可靠性。这四个特性分别是:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。下面详细解释每一个特性,并结合示例代码来说明它们在 MySQL 中的实现。

1. 原子性(Atomicity)

原子性确保事务中的所有操作要么全部成功,要么全部失败。事务的所有操作作为一个整体,一起提交或回滚。

示例代码

假设我们有一个 accounts 表,我们要从一个账户转账到另一个账户:

-- 创建 accounts 表
CREATE TABLE accounts (
    account_id INT AUTO_INCREMENT PRIMARY KEY,
    account_name VARCHAR(100) NOT NULL,
    balance DECIMAL(10, 2) NOT NULL
);

-- 插入初始数据
INSERT INTO accounts (account_name, balance) VALUES ('Alice', 1000.00);
INSERT INTO accounts (account_name, balance) VALUES ('Bob', 1000.00);

-- 开始事务
START TRANSACTION;

-- 从 Alice 的账户减去 100 元
UPDATE accounts SET balance = balance - 100 WHERE account_name = 'Alice';

-- 向 Bob 的账户增加 100 元
UPDATE accounts SET balance = balance + 100 WHERE account_name = 'Bob';

-- 如果两个操作都成功,则提交事务
COMMIT;

-- 如果有任何错误,则回滚事务
-- ROLLBACK;

在这个示例中,如果任何一个 UPDATE 操作失败,整个事务将会回滚,保证原子性。

2. 一致性(Consistency)

一致性确保事务执行前后,数据库从一个一致状态转换到另一个一致状态。所有约束(如外键约束、唯一性约束等)在事务执行前后都必须满足。

示例代码

在上面的示例中,如果 balance 列有一个检查约束确保余额不能为负数:

-- 添加约束,确保余额不能为负数
ALTER TABLE accounts ADD CONSTRAINT chk_balance CHECK (balance >= 0);

-- 开始事务
START TRANSACTION;

-- 从 Alice 的账户减去 1100 元(超过余额)
UPDATE accounts SET balance = balance - 1100 WHERE account_name = 'Alice';

-- 向 Bob 的账户增加 1100 元
UPDATE accounts SET balance = balance + 1100 WHERE account_name = 'Bob';

-- 提交事务(由于约束,事务会失败并回滚)
COMMIT;

-- 如果有任何错误,则回滚事务
-- ROLLBACK;

在这个示例中,由于违反了 CHECK 约束,事务将回滚,确保一致性。

3. 隔离性(Isolation)

隔离性确保并发事务之间互不干扰,一个事务的中间状态对其他事务不可见。MySQL 提供四种隔离级别:READ UNCOMMITTEDREAD COMMITTEDREPEATABLE READ(默认)和 SERIALIZABLE

示例代码

假设我们有两个并发事务:

-- 设置会话隔离级别为 REPEATABLE READ
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

-- 事务 A
START TRANSACTION;
SELECT balance FROM accounts WHERE account_name = 'Alice';

-- 等待事务 B 完成后继续
-- ...

-- 提交事务 A
COMMIT;

-- 事务 B
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE account_name = 'Alice';
COMMIT;

在这个示例中,事务 A 在读取 Alice 的余额后,事务 B 对 Alice 的余额进行了更新。由于隔离级别为 REPEATABLE READ,事务 A 在整个事务期间读取到的 Alice 余额是一致的,不会受到事务 B 的影响。

4. 持久性(Durability)

持久性确保一旦事务提交,所有修改将永久保存,即使系统崩溃也不会丢失。

示例代码
-- 开始事务
START TRANSACTION;

-- 更新操作
UPDATE accounts SET balance = balance - 100 WHERE account_name = 'Alice';
UPDATE accounts SET balance = balance + 100 WHERE account_name = 'Bob';

-- 提交事务
COMMIT;

在这个示例中,一旦事务提交,Alice 和 Bob 的账户余额修改将持久保存,即使系统崩溃也不会丢失。

事务的完整示例

以下是一个完整的事务示例,展示了 ACID 特性的实现:

-- 创建数据库
CREATE DATABASE bank;

-- 选择数据库
USE bank;

-- 创建 accounts 表
CREATE TABLE accounts (
    account_id INT AUTO_INCREMENT PRIMARY KEY,
    account_name VARCHAR(100) NOT NULL,
    balance DECIMAL(10, 2) NOT NULL,
    CONSTRAINT chk_balance CHECK (balance >= 0)
);

-- 插入初始数据
INSERT INTO accounts (account_name, balance) VALUES ('Alice', 1000.00);
INSERT INTO accounts (account_name, balance) VALUES ('Bob', 1000.00);

-- 设置会话隔离级别为 REPEATABLE READ
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

-- 开始事务
START TRANSACTION;

-- 从 Alice 的账户减去 100 元
UPDATE accounts SET balance = balance - 100 WHERE account_name = 'Alice';

-- 向 Bob 的账户增加 100 元
UPDATE accounts SET balance = balance + 100 WHERE account_name = 'Bob';

-- 插入转账记录到 transactions 表
INSERT INTO transactions (from_account, to_account, amount) 
SELECT a1.account_id, a2.account_id, 100
FROM accounts a1, accounts a2
WHERE a1.account_name = 'Alice' AND a2.account_name = 'Bob';

-- 提交事务,确保持久性
COMMIT;

-- 如果有任何错误,则回滚事务,确保原子性和一致性
-- ROLLBACK;

通过以上代码示例,展示了 MySQL 中如何实现 ACID 特性,确保数据库操作的可靠性和数据完整性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辞暮尔尔-烟火年年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值