Adi*_*Adi 6 sql-server triggers transactions try-catch
我有一个存储过程,在Insert/Update/Delete的触发器内调用.
问题是该SP内部存在某个代码块并不重要.因此,我想忽略此代码块产生的任何错误.
我在TRY CATCH块中插入了这个代码块.但令我惊讶的是我收到了以下错误:
当前事务无法提交,也无法支持写入日志文件的操作.回滚交易.
然后我尝试使用SAVE&ROLLBACK TRANSACTION和TRY CATCH,它也因以下错误而失败:
当前事务无法提交,也无法回滚到保存点.回滚整个交易.
我的服务器版本是:Microsoft SQL Server 2008(SP2) - 10.0.4279.0(X64)
样本DDL:
IF OBJECT_ID('TestTrigger') IS NOT NULL
DROP TRIGGER TestTrigger
GO
IF OBJECT_ID('TestProcedure') IS NOT NULL
DROP PROCEDURE TestProcedure
GO
IF OBJECT_ID('TestTable') IS NOT NULL
DROP TABLE TestTable
GO
CREATE TABLE TestTable (Data VARCHAR(20))
GO
CREATE PROC TestProcedure
AS
BEGIN
SAVE TRANSACTION Fallback
BEGIN TRY
DECLARE @a INT = 1/0
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION Fallback
END CATCH
END
GO
CREATE TRIGGER TestTrigger
ON TestTable
FOR INSERT, UPDATE, DELETE
AS
BEGIN
EXEC TestProcedure
END
GO
Run Code Online (Sandbox Code Playgroud)
用于复制错误的代码:
BEGIN TRANSACTION
INSERT INTO TestTable VALUES('data')
IF @@ERROR > 0
ROLLBACK TRANSACTION
ELSE
COMMIT TRANSACTION
GO
Run Code Online (Sandbox Code Playgroud)
小智 12
我经历了同样的折磨,我刚解决了!只需在TRIGGER的第一步添加这一行,您就可以了:
SET XACT_ABORT OFF;
Run Code Online (Sandbox Code Playgroud)
就我而言,我正在处理错误,该错误为导致错误的批处理和SQL中的错误变量提供了特定的表.
为默认值XACT_ABORT为ON,所以即使你正在处理一个try catch块(就像我做的)内部错误的整个交易将不被COMMITED.将其值设置为OFF将导致即使发生错误也会提交事务.
但是,当没有处理错误时我没有测试它...
欲了解更多信息:
我建议重新构建它,以便您不会毒害原始事务 - 也许让事务发送服务代理消息(或者只是将相关数据插入某种形式的队列表中),以便“非关键”部分可以在完全独立的交易中进行。
例如你的触发器变成:
CREATE TRIGGER TestTrigger
ON TestTable
FOR INSERT, UPDATE, DELETE
AS
BEGIN
INSERT INTO QueueTable (Col1,Col2)
SELECT COALESCE(i.Col1,d.Col1),COALESCE(i.Col2,d.Col2) from inserted i,deleted d
END
GO
Run Code Online (Sandbox Code Playgroud)
您不应该在触发器内执行任何可能失败的操作,除非您确实希望强制启动触发器操作的事务也失败。
| 归档时间: |
|
| 查看次数: |
10594 次 |
| 最近记录: |