BEGIN TRANSACTION (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse AnalyticsMicrosoft Fabric中的仓库Microsoft Fabric中的SQL数据库

标记一个显式本地事务的起始点。 显式事务以语句开头BEGIN TRANSACTION,以或COMMIT语句结尾ROLLBACK。

Transact-SQL 语法约定

Syntax

SQL Server、Azure SQL 数据库、Azure SQL 托管实例、Microsoft Fabric 中的 SQL 数据库的语法。

BEGIN { TRAN | TRANSACTION }
    [ { transaction_name | @tran_name_variable }
      [ WITH MARK [ 'description' ] ]
    ]
[ ; ]

Fabric Data Warehouse和Azure Synapse Analytics的语法。

BEGIN { TRAN | TRANSACTION }
[ ; ]

Arguments

transaction_name

适用于:SQL Server 2008(10.0.x)及更高版本、Azure SQL 数据库、Azure SQL 托管实例、Microsoft Fabric 中的 SQL 数据库。

分配给事务的名称。 transaction_name 必须符合标识符的规则,但不允许长度超过 32 个字符的标识符。 仅在最外部的 BEGIN...COMMIT 或 BEGIN...ROLLBACK 语句上使用事务名称。 transaction_name 始终区分大小写,即使数据库引擎实例不区分大小写也是如此。

@tran_name_variable

适用于:SQL Server 2008(10.0.x)及更高版本、Azure SQL 数据库、Azure SQL 托管实例、Microsoft Fabric 中的 SQL 数据库。

包含有效事务名称的用户定义变量的名称。 必须使用 char、varchar、nchar 或 nvarchar 数据类型声明该变量 。 如果将超过 32 个字符传递给变量,则仅使用前 32 个字符。 其余字符将被截断。

WITH MARK [ 'description' ]

适用于:SQL Server 2008(10.0.x)及更高版本、Azure SQL 数据库、Azure SQL 托管实例、Microsoft Fabric 中的 SQL 数据库。

指定事务在事务日志中标记。 description 是描述该标记的字符串。 将被截断为 128 个字符。

如果使用 WITH MARK ,则必须指定事务名称。 WITH MARK 允许将事务日志还原到标记标识的点。

Remarks

BEGIN TRANSACTION @@TRANCOUNT递增者1。

BEGIN TRANSACTION 表示会话引用的数据具有某种一致性状态的点。 可以回滚之后 BEGIN TRANSACTION 进行的所有数据修改,以将数据返回到此已知一致性状态。 每个事务一直持续到 COMMIT TRANSACTION 发出以使修改成为数据库的永久部分,或者所有修改都用 ROLLBACK TRANSACTION 语句擦除。

如果发生事务中止错误,或者发生任何运行时错误并且 XACT_ABORT 会话选项设置为 ON,则可以自动回滚事务。 有关详细信息,请参阅 SET XACT_ABORT。

BEGIN TRANSACTION 为发出语句的会话启动本地事务。 根据当前的事务隔离级别设置,为支持会话发出的 Transact-SQL 语句获取的资源被事务锁定,直到事务使用 COMMIT TRANSACTION 或 ROLLBACK TRANSACTION 语句完成。 长时间未完成的事务可能会阻止其他会话访问这些锁定的资源,还可以防止事务日志截断和版本存储清理。

虽然 BEGIN TRANSACTION 启动本地事务,但在应用程序执行必须在日志中记录的操作(如执行 INSERT、 UPDATE或 DELETE 语句)之前,不会在事务日志中记录该事务。 启动事务后,数据库引擎可以执行诸如获取锁之类的作来保护语句的 SELECT 事务隔离级别,但在应用程序执行修改作之前,事务日志中不会记录任何内容。

发出 BEGIN TRANSACTION后,可以再次发出问题 BEGIN TRANSACTION 以启动一个或多个内部事务。 即使可以为内部事务指定 transaction_name ,但系统只注册第一个(最外部)的事务名称。 回滚到任何其他名称(非有效的保存点名称)将生成错误,而无需回滚任何语句。 这些语句仅当外层的事务回滚时才会进行回滚。

如果在提交或回滚语句之前执行以下作,则语句启动 BEGIN TRANSACTION 的本地事务将提升为分布式事务:

  • INSERT执行引用链接服务器上的远程表的语句DELETEUPDATE。 INSERT如果用于访问链接服务器的 OLE DB 提供程序不支持UPDATE接口,则返回DELETE或ITransactionJoin语句失败。

  • 当 REMOTE_PROC_TRANSACTIONS 选项设置为 ON 时,将调用远程存储过程。

本地数据库引擎实例将成为事务控制器,并使用Microsoft分布式事务处理协调器(MS DTC)来管理分布式事务。

可以使用该事务作为分布式事务 BEGIN DISTRIBUTED TRANSACTION显式执行。 有关详细信息,请参阅 BEGIN DISTRIBUTED TRANSACTION。

设置为时SET IMPLICIT_TRANSACTIONS,语句ON将创建外部事务和内部事务,设置为 BEGIN TRANSACTION@@TRANCOUNT2。 有关详细信息,请参阅 SET IMPLICIT_TRANSACTIONS。

注释

数据库引擎不支持独立管理的嵌套事务。 内部事务的提交会递 @@TRANCOUNT 减,但没有任何其他影响。 内部事务的回滚始终回滚外部事务,除非 存在保存点 并在语句中 ROLLBACK 指定。

标记的事务

该 WITH MARK 选项会导致事务日志中记录事务名称。 将数据库还原到早期状态时,可以使用标记的事务来指定还原点,而不是日期和时间。 欲了解更多信息,请参见 “使用标记事务以一致恢复相关数据库 和 RESTORE 语句”。

此外,如果需要将一组相关数据库恢复到特定共享一致性状态,则需要事务日志标记。 了解每个数据库的一致性状态的应用程序可以使用跨数据库或分布式事务将标记置于相关数据库的事务日志中。 将相关数据库集恢复到这些标记会导致一组具有已知共享一致性状态的数据库。

只有当数据库由标记事务更新时,才在事务日志中放置标记。 不修改数据的事务不会记录在日志中。

BEGIN TRANSACTION <new_name> WITH MARK 可以在启动内部事务时使用。 在这种情况下,如果未标记外部事务, <new_name> 则成为事务的标记名称。 在以下概念示例中, M2 是标记的名称。

BEGIN TRAN T1;

UPDATE table1 ...;

BEGIN TRAN M2 WITH MARK;

UPDATE table2 ...;

SELECT column1 FROM table1;

COMMIT TRAN M2;

UPDATE table3 ...;

COMMIT TRAN T1;

标记内部事务时,如果尝试标记已标记的事务,将收到以下警告消息:

Server: Msg 3920, Level 16, State 1, Line 3
WITH MARK option only applies to the first BEGIN TRAN WITH MARK.
The option is ignored.

Permissions

要求具有 public 角色的成员身份。

Examples

本文中的代码示例使用AdventureWorks2025了 、 AdventureWorksDW2025或AdventureWorksLT2025示例数据库,您可以从 Azure Data SQL Samples Repository 的 GitHub 仓库下载。

A. 使用显式事务

适用于:SQL Server 2008 (10.0.x) 及以后版本,Azure SQL 数据库,Azure SQL 托管实例,Microsoft Fabric 中的 SQL 数据库,以及 Azure Synapse Analytics

BEGIN TRANSACTION;

DELETE FROM HumanResources.JobCandidate
WHERE JobCandidateID = 13;

COMMIT TRANSACTION;

B. 回滚事务

适用于:SQL Server 2008 (10.0.x) 及以后版本,Azure SQL 数据库,Azure SQL 托管实例,Microsoft Fabric 中的 SQL 数据库,以及 Azure Synapse Analytics

以下示例显示了回滚事务的效果。 在此示例中, ROLLBACK 该语句回滚 INSERT 该语句,但已创建的表仍然存在。

CREATE TABLE ValueTable
(
    id INT
);

BEGIN TRANSACTION;

INSERT INTO ValueTable VALUES (1);
INSERT INTO ValueTable VALUES (2);

ROLLBACK;

C. 为事务命名

适用于:SQL Server 2008 (10.0.x) 及更高版本、Azure SQL 数据库、Azure SQL 托管实例、Microsoft Fabric 中的 SQL 数据库

下面的示例说明如何命名事务。

DECLARE @TranName AS VARCHAR (20);
SELECT @TranName = 'MyTransaction';

BEGIN TRANSACTION @TranName;

DELETE FROM HumanResources.JobCandidate
WHERE JobCandidateID = 13;

COMMIT TRANSACTION @TranName;

D. 标记事务

适用于:SQL Server 2008 (10.0.x) 及更高版本、Azure SQL 数据库、Azure SQL 托管实例、Microsoft Fabric 中的 SQL 数据库

以下示例显示如何标记事务。 将标记事务 CandidateDelete。

BEGIN TRANSACTION CandidateDelete
    WITH MARK N'Deleting a Job Candidate';

DELETE FROM HumanResources.JobCandidate
WHERE JobCandidateID = 13;

COMMIT TRANSACTION CandidateDelete;