Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 与.NET TransactionScopeOption.Suppress等效的T-SQL_C#_Sql Server_Tsql_Transactions_Transactionscope - Fatal编程技术网

C# 与.NET TransactionScopeOption.Suppress等效的T-SQL

C# 与.NET TransactionScopeOption.Suppress等效的T-SQL,c#,sql-server,tsql,transactions,transactionscope,C#,Sql Server,Tsql,Transactions,Transactionscope,在.NET代码中,在数据库事务内部(使用),我可以包含一个带有TransactionScopeOption.Suppress的嵌套块,它确保即使外部块回滚,嵌套块内的命令也会提交。 以下是一个代码示例: using (TransactionScope txnScope = new TransactionScope(TransactionScopeOption.Required)) { db.ExecuteNonQuery(CommandType.Text, "Insert Into Bu

在.NET代码中,在数据库事务内部(使用),我可以包含一个带有
TransactionScopeOption.Suppress
的嵌套块,它确保即使外部块回滚,嵌套块内的命令也会提交。 以下是一个代码示例:

using (TransactionScope txnScope = new TransactionScope(TransactionScopeOption.Required))
{
    db.ExecuteNonQuery(CommandType.Text, "Insert Into Business(Value) Values('Some Value')");

    using (TransactionScope txnLogging = new TransactionScope(TransactionScopeOption.Suppress))
    {
        db.ExecuteNonQuery(CommandType.Text, "Insert Into Logging(LogMsg) Values('Log Message')");
        txnLogging.Complete();
    }

    // Something goes wrong here. Logging is still committed

    txnScope.Complete();
}
我想知道这是否可以用T-SQL实现。有几个人推荐了它,但它看起来不太“优雅”。此外,我认为将连接信息放在T-SQL代码中是个坏主意

我以前使用过SQL Service Broker,但它也支持事务性消息传递,这意味着在提交数据库事务之前,消息不会发布到队列


我的要求:我们的应用程序存储过程是由某个第三方应用程序在存储过程外部启动的隐式事务中启动的。我希望能够捕获并记录存储过程中的任何错误(在同一数据库的数据库表中)。我需要重新抛出异常,让第三方应用程序回滚事务,并让它知道操作失败(从而在失败的情况下执行所需的操作).

您可以设置一个环回链接服务器,将
远程过程事务升级
选项设置为false,然后在TSQL中访问它,或者使用SQL server中的CLR过程在事务外部创建一个新连接并执行您的工作

这两种方法都在本文中提出


这两种方法都涉及创建新连接。存在一个请求以本机方式提供此功能的问题。

表变量中的值存在于回滚之外

因此,在下面的示例中,由于和表变量的组合,所有要删除的行都可以插入到持久化表中并在以后查询

-- First, create our table
CREATE TABLE [dbo].[DateTest] ([Date_Test_Id] INT IDENTITY(1, 1), [Test_Date] datetime2(3));

-- Populate it with 15,000,000 rows
-- from 1st Jan 1900 to 1st Jan 2017.
INSERT INTO [dbo].[DateTest] ([Test_Date])
SELECT 
TOP (15000000)
    DATEADD(DAY, 0, ABS(CHECKSUM(NEWID())) % 42734)
    FROM [sys].[messages] AS [m1]
    CROSS JOIN [sys].[messages] AS [m2];

BEGIN TRAN;

BEGIN TRY

    DECLARE @logger TABLE ([Date_Test_Id] INT, [Test_Date] DATETIME);

    -- Delete every 1000 row
    DELETE FROM [dbo].[DateTest]
    OUTPUT deleted.Date_Test_Id, deleted.Test_Date INTO @logger
    WHERE [Date_Test_Id] % 1000 = 0;

    -- Make it fail
    SELECT 1/0

    -- So this will never happen
    COMMIT TRANSACTION;

END TRY
BEGIN CATCH

    ROLLBACK TRAN
    SELECT * INTO dbo.logger FROM @logger;

END CATCH;

SELECT * FROM dbo.logger;

DROP TABLE dbo.logger;

所以你的.NET代码被第三方.NET代码调用了?你看过变量表了吗?@usr-我不知道第三方应用程序代码。我在问题中发布的.NET代码只是为了说明我想在T-SQL代码中做同样的事情。@Shaneis-你是说表变量吗?这些有什么帮助?我想在一个永久数据库表中记录错误,该表恰好位于运行存储过程的数据库中。问题指出“第三方应用程序”正在回滚事务。回滚不在proc本身中(尽管如果在发生这种情况时是可选的,那么这将是一个更好的解决方案),CLR过程选项正在考虑之中。不过,环回链接服务器选项要简单得多。谢谢!链接服务器选项有任何明显的性能缺点吗?这只适用于特殊情况(主要是在存储过程的catch块中)。我能想到的主要事情是两个连接而不是一个连接,但听起来好像这不是一个常规的事情。