CodeGym /课程 /SQL SELF /深入了解事务

深入了解事务

SQL SELF
第 39 级, 课程 0
可用

我们之前在课程里已经提到过什么是事务。再提醒一下,事务就是一串必须作为一个整体执行的操作。比如你要做银行转账,这时候你要从一个账户扣钱,再把钱加到另一个账户。如果其中某一步失败了(比如钱扣了但没加上),那就麻烦大了。这时候事务就能帮上大忙。

事务要么全部执行,要么完全不执行。这就是“要么全有要么全无”的原则。

BEGIN;
-- 在一个账户上减少余额
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- 在另一个账户上增加余额
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT; -- 应用更改

如果哪里出错了,可以用ROLLBACK撤销更改。

什么是事务的ACID属性

说到PostgreSQL(其实所有关系型数据库)里的事务,经常会提到ACID,这可不是化学。ACID代表Atomicity(原子性)、Consistency(一致性)、Isolation(隔离性)、Durability(持久性)。这四个属性保证了数据处理的安全、顺序和可预期。

原子性(Atomicity)
事务要么全部完成,要么啥都不做。如果中间有一步出错——全部撤销。想象一下你转账时突然出错——要么全都取消,要么钱全都转过去。绝对没有“只做一半”的操作。

一致性(Consistency)
事务结束后,数据库会保持在正确、合理的状态。所有的规则、约束和表之间的关系都要满足。比如你不允许负余额,那违反这个规则的事务就不会被保存。

隔离性(Isolation)
一个事务没结束前,别的事务看不到它的中间数据。这能防止出现奇怪的情况,比如你在网店里钱已经扣了但商品还没加到订单里——这种体验很糟糕,对吧?

持久性(Durability)
只要事务成功完成,所有更改就一定会被保存。哪怕你刚提交完就断电——数据也还在。这就像点了“保存”按钮,完全不用担心丢数据。

这四个属性,就是事务在数据库里被认为可靠的根本原因。

事务应用场景举例

理论很重要,但事务的真正威力是在实际场景里体现出来的。比如涉及钱、有关联的表或者批量更改时,事务就是不可替代的工具。它们不仅让你能放心操作,还能避免数据丢失或让数据库变成“半瘫痪”状态。

下面是几个事务真的能救场的典型例子:

1. 支付处理

当客户把钱从一个账户转到另一个账户时,事务保证钱不会凭空消失:

BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT;

如果第一个账户余额不够,可以撤销更改:

BEGIN;
UPDATE accounts SET balance = balance - 500 WHERE account_id = 1;
-- 哎呀,余额变成负数了!
ROLLBACK;

2. 更新关联表

比如你要把学生的状态改成“已毕业”,同时在“毕业生”表里加一条记录:

BEGIN;
UPDATE students SET status = 'graduated' WHERE student_id = 42;
INSERT INTO graduates (student_id, graduation_date) VALUES (42, '2023-06-10');
COMMIT;

如果有一步失败了(比如INSERT出错),数据库会回到最初的状态。

3. 批量更新数据

事务很适合做大批量更新,比如:

BEGIN;
UPDATE orders SET status = 'completed' WHERE delivery_date < CURRENT_DATE;
COMMIT;

如果服务器挂了或者你发现更新错了,随时可以撤销更改!

事务相关命令

PostgreSQL有几个核心命令:

  • BEGIN: 开启新事务:

    BEGIN;
    
  • COMMIT: 提交(保存)事务里的所有更改:

    COMMIT;
    

ROLLBACK: 撤销当前事务里的所有更改:

ROLLBACK;

完整流程示例

BEGIN;
-- 一些操作
UPDATE accounts SET balance = balance - 200 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 200 WHERE account_id = 2;

-- 决定撤销更改
ROLLBACK;

-- 重新开始
BEGIN;
-- 同样的操作,但换个转账金额
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;

-- 完成事务
COMMIT;

事务在现实中的样子

网店。 很多平台用事务来管理订单和支付。比如订单只有在支付成功后才会被处理。如果哪里出错,订单会自动取消。

银行系统。 事务能保护你的钱不受断电等意外影响。

事务历史。 PostgreSQL会保存WAL(Write-Ahead Logging)日志,出故障时能恢复数据。这就是让事务靠谱的“魔法”。

下节课我们会更详细地讲BEGIN、COMMIT和ROLLBACK命令,还会看批量操作和用SAVEPOINT做部分回滚的例子。下次见!

2
任务
SQL SELF, 第 39 级, 课程 0
已锁定
使用事务进行批量更新
使用事务进行批量更新
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION