BEGIN TRANSACTION (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse AnalyticsAnalytics Platform System (PDW)Microsoft Fabric 中的仓库

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

Transact-SQL 语法约定

语法

SQL Server、Azure SQL 数据库和Azure SQL 托管实例的语法。

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

Microsoft Fabric、Azure Synapse Analytics 和 Analytics Platform System (PDW)中 Synapse 数据仓库的语法。

BEGIN { TRAN | TRANSACTION }
[ ; ]

注意

若要查看 SQL Server 2014 (12.x) 及更早版本的 Transact-SQL 语法,请参阅早期版本文档

参数

transaction_name

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

分配给事务的名称。 transaction_name 必须符合标识符的规则,但不允许长度超过 32 个字符的标识符。 仅在最外部的嵌套 BEGIN...COMMITBEGIN...ROLLBACK 语句对上使用事务名称。 即使 SQL Server 实例不区分大小写,transaction_name始终区分大小写。

@tran_name_variable

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

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

WITH MARK [ 'description' ]

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

指定在日志中标记事务。 description 是描述该标记的字符串在表中存储msdb.dbo.logmarkhistory之前,超过 128 个字符的说明将被截断为 128 个字符。

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

注解

BEGIN TRANSACTION@@TRANCOUNT递增者1

BEGIN TRANSACTION 表示连接引用的数据在逻辑上和物理上一致的点。 如果遇到错误,则可以回滚之后 BEGIN TRANSACTION 所做的所有数据修改,以将数据返回到此已知一致性状态。 每个事务一直持续到它完成且未出错并 COMMIT TRANSACTION 发出以使修改成为数据库的永久部分,或者遇到错误,并且所有修改都将用 ROLLBACK TRANSACTION 语句擦除。

BEGIN TRANSACTION 为发出语句的连接启动本地事务。 根据当前的事务隔离级别设置,为支持连接颁发的 Transact-SQL 语句而获取的许多资源被事务锁定,直到事务使用 COMMIT TRANSACTIONROLLBACK TRANSACTION 语句完成。 长时间处于未完成状态的事务会阻止其他用户访问这些锁定的资源,也会阻止日志截断。

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

在一系列嵌套的事务中用一个事务名给多个事务命名对该事务没有什么影响。 系统仅登记第一个(最外部的)事务名。 回滚到其他任何名称(有效的保存点名除外)都会产生错误。 事实上,回滚之前执行的任何语句都不会在错误发生时回滚。 这些语句仅当外层的事务回滚时才会进行回滚。

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

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

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

SQL Server 的本地副本成为事务控制器并且使用 Microsoft 分布式事务处理协调器 (MS DTC) 来管理分布式事务。

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

ON设置为时SET IMPLICIT_TRANSACTIONS,语句将创建两个BEGIN TRANSACTION嵌套事务。 有关详细信息,请参阅 SET IMPLICIT_TRANSACTIONS

标记的事务

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 * 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.

权限

要求 公共 角色具有成员身份。

示例

本文中的 Transact-SQL 代码示例使用 AdventureWorks2022 示例数据库,可从 Microsoft SQL Server 示例和社区项目主页下载它。

A. 使用显式事务

适用于:SQL Server 2008(10.0.x)及更高版本、Azure SQL 数据库、Azure SQL 托管实例、Azure Synapse Analytics、Analytics Platform System (PDW)

BEGIN TRANSACTION;
DELETE FROM HumanResources.JobCandidate
    WHERE JobCandidateID = 13;
COMMIT;

B. 回滚事务

适用于:SQL Server 2008(10.0.x)及更高版本、Azure SQL 数据库、Azure SQL 托管实例、Azure Synapse Analytics、Analytics Platform System (PDW)

以下示例显示了回滚事务的效果。 在此示例中, 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 托管实例

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

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

BEGIN TRANSACTION @TranName;
USE AdventureWorks2022;
DELETE FROM AdventureWorks2022.HumanResources.JobCandidate
    WHERE JobCandidateID = 13;

COMMIT TRANSACTION @TranName;
GO

D. 标记事务

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

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

BEGIN TRANSACTION CandidateDelete
    WITH MARK N'Deleting a Job Candidate';
GO
USE AdventureWorks2022;
GO
DELETE FROM AdventureWorks2022.HumanResources.JobCandidate
    WHERE JobCandidateID = 13;
GO
COMMIT TRANSACTION CandidateDelete;
GO