1 /以下代码片段显示了预期的错误:INSERT语句与FOREIGN KEY约束FK _...冲突.
SET XACT_ABORT ON;
BEGIN TRANSACTION
INSERT INTO linkedsrv1.db1.[dbo].tbl1 ([Col1], [Col2])
VALUES (1200, 0)
COMMIT TRANSACTION
Run Code Online (Sandbox Code Playgroud)
2 /但是当我把它放在BEGIN TRY/CATCH中时,错误消息是模糊的:消息1206,级别18,状态118,行18 Microsoft分布式事务处理协调器(MS DTC)已取消分布式事务.
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRANSACTION
-- Error is on this line
INSERT INTO linkedsrv1.db1.[dbo].tbl1 ([IdWebsite], [IdProductType])
VALUES (1200, 0)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
PRINT 'Error' -- Code not reached
SELECT ERROR_NUMBER(), ERROR_MESSAGE(), ERROR_SEVERITY(), ERROR_STATE()
IF XACT_STATE() != 0
ROLLBACK TRANSACTION
END CATCH
Run Code Online (Sandbox Code Playgroud)
知道为什么会这样吗?
稍后编辑:
它适用于我删除不需要的显式事务.当我放入BEGIN/COMMIT TRAN时,我仍然不清楚为什么会出现这个错误.
如果我在链接服务器上的多个表中有多个插入,我会得到相同的错误.
欢迎任何评论/评论.
小智 6
来自MSDN:
请考虑以下情形.您使用SQL Server 2005中的SQL Native Client OLE DB提供程序(SQLNCLI)来创建链接服务器.您创建分布式事务.分布式事务包含使用链接服务器从表中检索数据的查询.提交分布式事务时,您可能会收到以下错误消息:
Msg 1206, Level 18, State 167, Line 3
The Microsoft Distributed Transaction Coordinator (MS DTC) has cancelled
the distributed transaction.
Run Code Online (Sandbox Code Playgroud)
此外,在发生此行为后运行查询时,您可能会收到以下错误消息:
Msg 8525, Level 16, State 1, Line 1
Distributed transaction completed. Either enlist this session in a new
transaction or the NULL transaction.
Run Code Online (Sandbox Code Playgroud)
如果满足以下条件,则会发生此问题:
You use the SQLNCLI provider to create a linked server between two
instances of SQL Server 2005.
The XACT_ABORT option is set to ON.
In the distributed transaction, you try to release a rowset before
all rows in the rowset are processed.
Run Code Online (Sandbox Code Playgroud)
注意如果在分布式事务中调用ReleaseRows方法以在应用程序中提交分布式事务之前释放行集,也可能会出现此问题.
出现此问题的原因是SQLNCLI提供程序错误地向链接服务器发送注意信号以回滚分布式事务.
若要防止SQLNCLI提供程序向服务器发送注意信号,请使用SQLNCLI提供程序完全使用OLE DB使用者创建的任何行集.
您需要在服务器参数中将"remote proc trans"配置为"1".
例如:
exec sp_configure'remote proc trans','1'使用override重新配置
这将使您执行任何分布式查询.
如果您也在前端使用.Net框架,那么我认为您可以使用 TransactionScope类.从查询中删除事务并将事务置于代码级别.
小智 4
我已经经历过这种痛苦了!如果您在单个表上执行任何 CRUD 操作,则不需要 TRANSACTION。
在这种情况下,问题是XACT_STATE()返回 -1,因为活动事务中存在错误。但是,ROLLBACK TRANSACTION失败了,因为没有发生任何交易。您只执行了一项事务,INSERT该事务失败了,因此没有其他事务可以回滚。
@@TRANCOUNT继续传递总是比XACT_STATE()(至少在这种情况下)更好。
要使其工作,请像这样进行更改(尽管我不支持单表的 TRAN):
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION
| 归档时间: |
|
| 查看次数: |
8230 次 |
| 最近记录: |