SQL Server 中事务的正确使用
Posted
技术标签:
【中文标题】SQL Server 中事务的正确使用【英文标题】:Correct use of transactions in SQL Server 【发布时间】:2012-04-26 13:46:53 【问题描述】:我有 2 个命令,需要它们都正确执行或都不执行。所以我想我需要一个事务,但我不知道如何正确使用它。
以下脚本有什么问题?
BEGIN TRANSACTION [Tran1]
INSERT INTO [Test].[dbo].[T1]
([Title], [AVG])
VALUES ('Tidd130', 130), ('Tidd230', 230)
UPDATE [Test].[dbo].[T1]
SET [Title] = N'az2' ,[AVG] = 1
WHERE [dbo].[T1].[Title] = N'az'
COMMIT TRANSACTION [Tran1]
GO
INSERT
命令执行了,但是UPDATE
命令有问题。
如果其中任何一个命令在执行过程中出现错误,我该如何实现它以回滚这两个命令?
【问题讨论】:
【参考方案1】:添加一个try/catch块,如果事务成功则提交更改,如果事务失败则回滚事务:
BEGIN TRANSACTION [Tran1]
BEGIN TRY
INSERT INTO [Test].[dbo].[T1] ([Title], [AVG])
VALUES ('Tidd130', 130), ('Tidd230', 230)
UPDATE [Test].[dbo].[T1]
SET [Title] = N'az2' ,[AVG] = 1
WHERE [dbo].[T1].[Title] = N'az'
COMMIT TRANSACTION [Tran1]
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION [Tran1]
END CATCH
【讨论】:
不应该把BEGIN TRANSACTION [Tran1]
放在TRY
里面吗?无论如何 - 非常简单和优雅的代码。
@PiotrNawrot 否,如果事务创建失败,则无需在 catch 中回滚。
如果您想查看错误,请将其包含在 catch 中:SELECT ERROR_MESSAGE() AS ErrorMessage;
@KevinLeStarge 或简单的THROW;
,如果您使用的是 SQL Server >= 2012,如上所述 here【参考方案2】:
在存储过程的开头应该输入SET XACT_ABORT ON 来指示Sql Server 自动回滚事务以防出错。如果省略或设置为 OFF,则需要在每个语句之后测试 @@ERROR 或使用 TRY ... CATCH rollback 块。
【讨论】:
换句话说,除非您先 SET XACT_ABORT ON,否则您的事务不是原子的。 带有下划线的url很难看,但是XACT_ABORT
中有下划线【参考方案3】:
简单的方法:
CREATE TABLE T
(
C [nvarchar](100) NOT NULL UNIQUE,
);
SET XACT_ABORT ON -- Turns on rollback if T-SQL statement raises a run-time error.
SELECT * FROM T; -- Check before.
BEGIN TRAN
INSERT INTO T VALUES ('A');
INSERT INTO T VALUES ('B');
INSERT INTO T VALUES ('B');
INSERT INTO T VALUES ('C');
COMMIT TRAN
SELECT * FROM T; -- Check after.
DELETE T;
【讨论】:
以上是关于SQL Server 中事务的正确使用的主要内容,如果未能解决你的问题,请参考以下文章