在SQL Server 2005中模拟自治事务

时间:2011-01-19 16:24:31

标签: sql-server sql-server-2005 transactions sqlclr

即使我的事务被回滚,我也需要将一些日志数据保存在不同的表中。

我已经了解到在SQL Server中不可能做到这样的事情

begin tran t1
insert ...
insert ...
select ...
       begin tran t2
         insert into log
       commit tran t2
rollback tran t1
select * from log -- IS EMPTY ALWAYS

所以我尝试 hacking SQL Server,我将CLR用于将LOG需要LOG导出到XML格式的本地服务器磁盘。 CLR代码很简单,因为它可以:

File.WriteAllText(fileName, xmlLog.Value.ToString());

在我在生产基地发布之前,我很想听听你对这项技术的强硬态度。

以下是几个问题:

  • 是否有其他更好的方法可以在SQL Server 2005中完成自治事务
  • 当SQL Server执行CLR时,如何保持我的事务未提交(SQL编写的数据量相对较小,约为50 - 60个记录,包括3个整数和4个浮点数)

1 个答案:

答案 0 :(得分:3)

我建议使用表变量,因为它不受事务的影响(这是Martin在问题下面的博客中列出的方法之一)。考虑这样做,这将在SQL Server 2005中起作用:

DECLARE @TempLog TABLE (FieldList...)

BEGIN TRY

    BEGIN TRAN

    INSERT...

    INSERT INTO @TempLog (FieldList...) VALUES (@Variables or StaticValues...)

    INSERT...

    INSERT INTO @TempLog (FieldList...) VALUES (@Variables or StaticValues...)

    COMMIT TRAN

END TRY
BEGIN CATCH

    IF (@@TRANCOUNT > 0)
    BEGIN
        ROLLBACK TRAN
    END

    /* Maybe add a Log message to note that we ran into an error */
    INSERT INTO @TempLog (FieldList...) VALUES (@Variables or StaticValues...)

END CATCH

INSERT INTO RealLogTable (FieldList...)
    SELECT FieldsList
    FROM @TempLog

请注意,虽然我们正在利用表变量不属于事务的这一事实,但这确实会产生一种潜在的情况,即此代码在INSERT INTO RealLogTable和您之前执行COMMIT但错误(或服务器崩溃)将丢失对其进行数据记录的日志记录。此时会出现断开连接,因为有数据,但就RealLogTable而言,没有插入记录。但这只是能够绕过交易的明显权衡。