跳至内容

理解 SQL 事务:全面指南

了解 SQL 事务、其重要性,以及如何实现它以构建可靠的数据库管理。
更新 2026年7月27日  · 9分钟

用 AI 探索

在 ChatGPT 中打开在 Claude 中打开在 Perplexity 中打开

SQL 事务是数据库管理中的重要组成部分,旨在确保您的数据始终准确可靠。我甚至认为,它们是维护任何应用中数据完整性的基础。

在本指南中,我们将从零开始讲解 SQL 事务,涵盖您需要了解的一切。如果您想进一步提升 SQL 技能,强烈推荐根据您的熟悉程度选择我们的 Introduction to SQL 或 Intermediate SQL Server 课程。两门课程都很受欢迎,通过结构化练习与实际用例,能帮助您夯实 SQL 基础。

什么是 SQL 事务?

SQL 事务确保一系列 SQL 操作作为单一、统一的过程执行,因此是维护数据完整性的有力工具。它们可用于多种场景,例如更新表中的多行或在账户间转账。事务通过将操作归为一个逻辑单元来工作,从而保证一致性并避免中断。

SQL 事务的目的

一项SQL 事务 是由一个或多个数据库操作(如 INSERTUPDATEDELETE)组成的序列,被视为一个不可分割的工作单元。在事务中,要么事务内的所有更改都成功应用,要么全部不应用。这确保数据库保持一致且不被破坏。

例如,设想在两个银行账户之间转账:

  1. 从账号 A 扣除 $100。
  2. 向账号 B 增加 $100。

如果没有使用事务,其中一个操作失败,您将面临数据不一致的风险——钱被扣了却未到账。将这些步骤归入一个事务,可以确保两个操作要么都成功,要么都不执行。

事务的关键属性:ACID

ACID 属性决定了事务的可靠性:

属性 描述 现实类比
原子性(Atomicity) 确保事务的各个部分要么全部完成,要么全部不执行。 电灯开关:要么完全开,要么完全关——不存在中间状态。
一致性(Consistency) 保证事务执行后数据库仍处于有效状态,并遵循规则与约束。 天平:一边加上重量,另一边会调整以保持平衡。
隔离性(Isolation) 防止事务相互干扰,确保数据处理仿佛每个事务都是独立运行的。 超市结账:队伍中的每个人都分别结账,不会把商品混在一起。
持久性(Durability) 确保一旦事务提交,其更改将是永久性的,即使系统发生故障。 保存文档:即使电脑崩溃,它仍然保持完整。

原子性:确保事务完整

原子性意味着事务是“要么全有、要么全无”。如果事务的任何部分失败,整个事务将回滚,数据库保持不变。例如:

BEGIN TRANSACTION;

UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
-- Commit only if both operations succeed
COMMIT;

如果第二条 UPDATE 语句出错,数据库会恢复到原始状态,确保不会出现部分更改。

一致性:维护数据库规则

一致性确保事务将数据库从一个有效状态带到另一个有效状态。这意味着在整个事务期间,所有规则、约束和关系都得到维护。

例如,如果某列有 NOT NULL 约束,那么试图插入 NULL 值的事务将失败,从而维护数据完整性。

隔离性:防止事务互相干扰

隔离性确保即使同时执行多个事务,它们也不会发生冲突。例如,如果两个用户更新同一条记录,隔离性可防止一方的更改覆盖或破坏另一方的更改。

不同的隔离级别(如 READ COMMITTEDSERIALIZABLE)决定这种隔离的严格程度,以平衡性能与一致性。

持久性:使更改永久生效

持久性保证一旦事务提交,数据库中的更改就是永久的,即使系统发生故障也是如此。数据库通过将已提交的事务写入非易失性存储来实现持久性。

例如,草稿邮件被安全地保存,即使电脑崩溃也能找回。

我建议学习我们的 Transactions and Error Handling in SQL Server 课程,它能帮助您掌握诸如错误处理等重要 SQL 概念。

如何实现 SQL 事务

要使用 SQL 事务,我们会用到 BEGINCOMMITROLLBACK 等命令,从而有效管理事务、将操作分组并处理错误。

使用 BEGIN、COMMIT 和 ROLLBACK

  1. BEGIN标记事务的开始。随后所有操作都属于该事务。

  2. COMMIT:提交事务,使所有更改在数据库中永久生效。

  3. ROLLBACK:撤销事务期间进行的所有更改;在发生错误或失败时,将数据库恢复到先前状态。

下面是一个简单的流程:

BEGIN TRANSACTION; -- Start the transaction
-- Perform database operations
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
COMMIT; -- Finalize the transaction

如果发生错误,您可以改为回滚事务:

BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- Simulate an error
ROLLBACK; -- Undo the changes

事务实现的实践示例

如前所述,通过将相关操作分组,事务可确保要么所有更改都成功应用,要么全部不应用,从而避免不一致状态。下面用真实场景演示事务在实践中的运作方式。

示例 1:账户间转账

在银行系统中,账户间转账需要借记一个账户并贷记另一个账户。事务可确保这两个操作同时成功或同时失败。

BEGIN TRANSACTION;
-- Deduct $500 from account A
UPDATE accounts SET balance = balance - 500 WHERE account_id = 1;
-- Add $500 to account B
UPDATE accounts SET balance = balance + 500 WHERE account_id = 2;
-- Commit the transaction
COMMIT;
If an error occurs, such as insufficient funds, the transaction can be rolled back:
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 500 WHERE account_id = 1;
-- Check for errors (pseudo-code for demonstration)
-- IF insufficient_balance THEN
ROLLBACK;
-- ELSE Commit the transaction
COMMIT;

示例 2:电商库存处理

设想一个电商平台,需要在同一事务中同时更新库存并记录销售。

BEGIN TRANSACTION;
-- Reduce inventory for the purchased product
UPDATE inventory SET stock = stock - 1 WHERE product_id = 101;
-- Record the sale in the orders table
INSERT INTO orders (order_id, product_id, quantity) VALUES (12345, 101, 1);
-- Commit the transaction
COMMIT;
```SQL
If an error occurs, such as trying to sell an out-of-stock product, the transaction can be rolled back to ensure consistency.
```SQL
BEGIN TRANSACTION;
UPDATE inventory SET stock = stock - 1 WHERE product_id = 101;
-- Check stock levels (pseudo-code)
-- IF stock < 0 THEN
ROLLBACK;
-- ELSE Record the sale and commit
INSERT INTO orders (order_id, product_id, quantity) VALUES (12345, 101, 1);
COMMIT;

高效事务管理的建议

有效管理事务是维护数据库完整性并确保流程顺畅的关键。无论您处理的是金融更新还是复杂数据集,遵循最佳实践都能避免问题。以下建议可帮助您优化事务处理:

  • 将关键操作放入事务:把必须同时成功或同时失败的操作(如金融更新或多表插入)分组处理,正如我们在示例中所见。

  • 设置错误处理机制:始终预判潜在错误,并使用 ROLLBACK 维护数据完整性。

  • 测试您的事务:模拟不同场景,确保事务逻辑在各种条件下都能正确运行。

深入理解并正确实施事务能显著提升数据库的健壮性,并让您更好地应对更高级的 SQL 挑战。要系统学习,请探索我们的 SQL Fundamentals 技能路径,提升您的数据库管理能力。

SQL 事务中的常见挑战与解决方案

要高效管理 SQL 事务,需要处理诸如死锁、并发以及数据完整性等问题。理解这些挑战并采取合适策略,才能确保事务处理顺畅。

应对死锁与并发

当多个事务争用共享资源时,数据库系统中常会出现死锁和并发问题。这些问题会影响数据库性能,导致操作变慢甚至停滞。实施有效策略对于维持系统平稳运行至关重要。

识别与解决死锁

死锁是指两个或多个事务相互等待对方持有的资源,导致彼此无限阻塞。处理死锁可遵循以下步骤:

1. 识别死锁

  • 使用数据库日志或监控工具实时检测死锁。
  • 现代关系型数据库管理系统(RDBMS),如 PostgreSQL 和 SQL Server,通常内置自动检测并终止死锁的机制。

2. 解决死锁

  • 在应用中实现重试逻辑,在死锁解除后重新执行失败的事务。
  • 在各事务中建立一致的资源访问顺序,以降低死锁风险。

资源排序示例:

-- Example of resource ordering to prevent deadlocks
BEGIN TRANSACTION;
UPDATE table_a SET col = 'value' WHERE id = 1;
UPDATE table_b SET col = 'value' WHERE id = 2;
COMMIT;

管理并发的技术

并发问题发生在多个事务同时访问共享资源、可能引发冲突或数据不一致的情况下。常见的两种应对技术包括:

锁机制

锁用于控制对资源的访问并确保事务完整性。共享锁允许多个事务读取同一资源,同时阻止修改,从而在读取期间保持数据一致。相对地,排他锁会限制其他事务访问该资源,确保独占写入。

应用锁的示例:

SELECT * FROM inventory WITH (ROWLOCK, HOLDLOCK) WHERE product_id = 101;

隔离级别

隔离级别决定事务之间如何交互,并在性能与数据一致性之间取得平衡。例如:

  • Read Uncommitted 许脏读,通过最小化锁开销来提升性能。

  • Serializable 提供最高级别的一致性,完全隔离事务,但可能降低并发性。

Setting a transaction to the Serializable isolation level:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;  
BEGIN TRANSACTION;  
-- Transaction logic  
COMMIT;  

确保数据完整性与错误处理

在事务中维护数据完整性对于防止部分更新或损坏状态至关重要。健全的错误处理机制还能进一步确保数据库操作的可靠性。

使用保存点进行部分回滚

保存点(Savepoints)允许您在事务内部创建检查点。如果发生错误,可以回滚到某个保存点,而无需撤销整个事务。

-- Start Transaction
BEGIN TRANSACTION;
-- Savepoint for first operation
SAVEPOINT step1;
-- First Operation: Debit Account 1
UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
-- Optional: Rollback to step1 if needed
-- ROLLBACK TO step1; 
-- Second Operation: Credit Account 2
UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
-- Commit Transaction
COMMIT;

保存点为复杂且包含多步的事务提供了更细粒度的控制。

实施错误处理机制

有效的错误处理确保事务要么成功完成,要么在出错时优雅失败。关键策略包括:

  1. TRY CATCH 代码块:在事务块中动态处理错误。

  2. 事务日志:维护日志以跟踪错误与事务状态。

-- Example of error handling with TRY CATCH
BEGIN TRY
    BEGIN TRANSACTION;
    UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
    UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
    COMMIT;
END TRY
BEGIN CATCH
    ROLLBACK;
    PRINT 'Transaction failed and rolled back.';
END CATCH;

借助这些机制,您可以从意外错误中恢复,并确保数据完整性得到维护。

解决死锁、并发与错误处理等挑战,对于实现稳健的事务管理至关重要。设置合适的隔离级别、使用保存点以及实现 TRY...CATCH 代码块,不仅能够维护数据完整性,还能提升系统可靠性。

SQL 事务的进阶概念

接下来这一部分将介绍嵌套事务、保存点,以及跨多个数据库的分布式事务。我推荐我们的 Introduction to Oracle SQL 课程来学习这类更高级的主题。

嵌套事务与保存点

嵌套事务指在事务中再嵌套事务。虽然不是所有 RDBMS 都直接支持,但可以通过保存点来模拟,从而对操作进行更细致的控制。

保存点允许在单个事务内进行部分回滚,使您能在较大的事务中,对特定部分的错误实现隔离与恢复。

保存点的工作方式:

  1. 开始一个事务。
  2. 在事务的关键阶段定义保存点。
  3. 若出现问题,回滚到某个保存点,而不是放弃整个事务。
  4. 在所有操作成功后提交事务。

示例:使用保存点模拟嵌套事务

BEGIN TRANSACTION;
-- Step 1: Create a savepoint
SAVEPOINT step1;
-- Step 2: Execute an operation
UPDATE inventory SET quantity = quantity - 10 WHERE product_id = 1;
-- Step 3: Create another savepoint
SAVEPOINT step2;
-- Step 4: Execute another operation
UPDATE inventory SET quantity = quantity + 10 WHERE product_id = 2;
-- Roll back to a savepoint if needed
ROLLBACK TO step2;
-- Finalize the transaction
COMMIT;

保存点在管理复杂事务逻辑时提供灵活性,允许您在提交前先对更小的操作块进行测试与验证。

跨多个数据库的分布式事务

分布式事务涉及在多个数据库之间协调操作以确保一致性。这类事务对于分布式架构(如微服务或数据集成流水线)的系统尤为重要。

分布式事务的挑战

  1. 数据一致性:确保各数据库在彼此独立的情况下仍能保持同步状态。
  2. 网络延迟:数据库之间的通信延迟会使事务时序变得复杂。
  3. 部分失败:若一个数据库提交而另一个失败,系统整体可能出现不一致。

分布式事务的解决方案

高级协议如两阶段提交(2PC)三阶段提交(3PC)可用于应对这些挑战。

  • 两阶段提交(2PC)
    • 第一阶段:准备 —— 所有数据库确认已准备好提交。
    • 第二阶段:提交 —— 若所有参与方同意,则提交事务;否则回滚。
  • 三阶段提交(3PC) 增加了预提交阶段,以应对 2PC 中的网络故障等问题。

结语

掌握 SQL 事务对于任何开发者或数据库管理员而言都大有裨益。入门时,我建议先理解 ACID 的基础知识,然后用 BEGINCOMMITROLLBACK 实践基本实现,再逐步深入到嵌套事务与分布式事务等高级概念。

若想获得具体的 SQL 技能提升建议,可以学习我们的 Intermediate SQL Server 课程。若您想要与本文内容相似、但更详细并配有练习题的结构化课程,推荐 Transactions and Error Handling in SQL Server 课程。两门课程结合学习将有助于您成为一名出色的开发者。我也撰写了关于 SQL Triggers 的文章,这是 SQL 开发者的另一项重要主题,欢迎查阅!

SQL 事务常见问答

什么是 SQL 事务?

SQL 事务是一系列作为单一逻辑工作单元执行的操作,旨在确保数据完整性。

为什么 SQL 事务很重要?

SQL 事务通过将操作组合为一个单元来维护数据库的数据完整性与一致性,因此至关重要。

SQL 事务中的 ACID 属性是什么?

ACID 属性——原子性、一致性、隔离性、持久性——确保事务可靠且一致。

如何在 SQL 中实现事务?

使用 BEGINCOMMITROLLBACK 语句即可在 SQL 中管理事务。

什么是 SQL 事务中的死锁?

死锁是指两个或多个事务相互等待对方持有的资源而彼此阻塞的情况。

如何解决 SQL 中的死锁?

可通过识别涉及的事务并采用超时或基于优先级的策略来解决死锁。

什么是 SQL 事务中的保存点?

保存点允许在事务中进行部分回滚,为事务管理提供更强控制力。

什么是嵌套事务?

嵌套事务是在一个事务中包含另一个事务,用于实现复杂的事务管理。

分布式事务如何工作?

分布式事务跨多个数据库执行,需要协调来确保所有相关系统的一致性。

错误处理在 SQL 事务中起什么作用?

错误处理确保事务成功完成,或在出错时回滚,从而维护数据完整性。

主题

在 DataCamp 学习 SQL 与数据工程

Courses

SQL Server 中的事务与错误处理

4小时
16.3K
学习编写脚本,捕获并处理错误,并控制同时发生的多个操作。
查看详情Right Arrow
开始课程
查看更多Right Arrow