
[英]How to set “SET XACT_ABORT ON ” in a SQL Server transaction?
[英]SET XACT_ABORT ON Being ignored, transaction continues (SQL Server 2008 R2)
也许我缺少了一些东西,但是即使下面的RAISERROR
的严重性为16(根据文档),事务仍将提交,就像XACT_ABORT ON
无效一样。
CREATE PROCEDURE [ExploringGroups].[RemoveMember]
@groupId uniqueidentifier,
@adminUsername nvarchar(50),
@targetUsername nvarchar(50)
AS
SET XACT_ABORT ON
BEGIN TRANSACTION
DECLARE
@adminUserId uniqueidentifier = dbo.fn_userId(@adminUsername),
@targetUserId uniqueidentifier = dbo.fn_userId(@targetUsername)
IF @targetUserId IS NULL OR ExploringGroups.IsMember(@groupId, @targetUserId) = 0
RAISERROR('Target user was not located', 16, 1)
IF ExploringGroups.IsInRole(@groupId, @adminUserId, 'adm') = 0
RAISERROR('Specified user is not an administrator of this group', 16, 2)
IF @adminUserId = @targetUserId
RAISERROR('You cannot remove yourself', 16, 3)
-- statements below still execute and commit even though there was an error raised above
DELETE FROM ExploringGroups.MemberRole WHERE GroupId = @groupId AND UserId = @targetUserId
DELETE FROM ExploringGroups.Membership WHERE GroupId = @groupId AND UserId = @targetUserId
COMMIT
RETURN 0
呼唤
exec exploringgroups.removemember '356048C5-BAB3-45C9-BE3C-A7227225DFDD', 'Crypton', 'Crypton'
产生
消息50000,级别16,状态2,过程RemoveMember,第20行
指定的用户不是该组的管理员
消息50000,级别16,状态3,过程RemoveMember,第24行
你不能删除自己
我以为XACT_ABORT
应该设置为ON
来回退整个事务?
实际上,它的行为完全符合预期。 XACT_ABORT
确实导致事务回滚,因此,如果有任何数据修改直到错误点,它们都将被回滚。 但是,它并没有影响执行流程,也没有停止运行存储过程,因此以下两个DELETE作为隐式事务被执行。 明确的RAISERROR不会中止该批处理。
请参阅以下简化版本:
create table #t(i int);
insert #t values(1);
go
alter procedure sp
as
set xact_abort on
begin tran
raiserror ('x', 16, 1);
print 'deleting';
delete #t;
commit;
go
exec sp
go
select * from #t
go
唯一可笑的是,关于COMMIT没有相应的BEGIN TRAN的错误被吞没了。
使用SEH,它将跳到CATCH块中。
您应该使用“ THROW”语句而不是RAISERROR方法。
使用BEGIN TRY和BEGIN CATCH并正常提交事务或在CATCH块中回滚。
BEGIN TRY-执行插入或抛出错误-提交事务END TRY BEGIN CATCH-回滚END CATCH;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.