1

我有用于将数据插入表的存储过程。此过程从处理事务启动、提交和回滚功能的 asp.net 应用程序调用。在存储过程内部没有事务。

在这种情况下,我的应用程序运行良好,并且它是实时托管的。现在,在存储过程中,我必须添加一个新功能,通过链接服务器将另一个表插入另一个数据库,如果出现错误,我必须将它存储在数据库中。

我们希望以这样的方式实现这种插入,以便之前的 sp 可以正常工作。

请注意,如果插入链接服务器出现错误,则整个过程将回滚,并且保存点也不起作用。我们可以通过 dot net 代码来做到这一点,但这适用于 40 多个模块,所以我必须通过 sp 来做到这一点。那么,我们如何实现这一点。

4

2 回答 2

0

有两种可接受的方式来逃避当前事务回滚 tarpit。

一种方法是使用环回连接。通过链接服务器或从 SQLCLR 连接回当前服务器并写入INSERT,确保不允许 DTC 注册。由于环回连接是不同的事务,您可以安全地回滚原始事务并保留 INSERT。这种方法的缺点是很容易让自己陷入僵局。

另一种鲜为人知的方法是用于sp_trace_generateevent触发用户可配置的事件。这可能看起来不多,但您可以为这些事件创建事件通知,然后在处理事件时执行 INSERT 处理。例如。请参阅事务中的 Sql 进度记录。这种方法的缺点是困难。

于 2013-10-29T13:20:11.400 回答
0

MSDN 保存事务

CREATE PROCEDURE [dbo].[SaveCustomer]
@Firstname nvarchar(50),
@Lastname nvarchar(50)
AS

DECLARE @ReturnCode int = 1     -- 1 - success
    ,@NewID int
---------------------------------------------- These variables are for TRY/CATCH RAISEERROR and BEGIN TRAN/SAVE POINT use           
    ,@tranCounter int               -- @TranCounter > 0 means an active transaction was started before the procedure was called.
    ,@errorMessage nvarchar(4000)   -- echo error information to the caller.  Message text.
    ,@errorSeverity int             -- Severity.
    ,@errorState int;               -- State

SET @tranCounter = @@TRANCOUNT;
IF @tranCounter > 0
    SAVE TRANSACTION SaveCustomer_Tran;
ELSE
    BEGIN TRANSACTION;

BEGIN TRY

    INSERT dbo.Customer (
        Firstname
        ,Lastname)
    VALUES (
        @Firstname
        ,@Lastname)

    SET @NewID = scope_identity()

    IF @tranCounter = 0
        COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    IF @tranCounter = 0
        ROLLBACK TRANSACTION;
    ELSE
        IF XACT_STATE() <> -1
            ROLLBACK TRANSACTION SaveCustomer_Tran;

    SELECT @errorMessage = 'Error in [SaveCustomer]: ' + ERROR_MESSAGE(), @errorSeverity = ERROR_SEVERITY(), @errorState = ERROR_STATE();

    RAISERROR (@errorMessage, @errorSeverity, @errorState);
    SET @ReturnCode = -1
END CATCH

SELECT @ReturnCode as [ReturnCode], @NewID as  [NewID]
GO
于 2013-10-29T13:08:01.047 回答