【问题标题】:Get a System.Data.SqlClient.SqlTransaction from a System.Transactions.TransactionScope从 System.Transactions.TransactionScope 获取 System.Data.SqlClient.SqlTransaction
【发布时间】:2014-09-22 15:04:16
【问题描述】:

有没有办法从System.Transactions.TransactionScopeSystem.Data.SqlClient.SqlConnection 的实例中获取System.Data.SqlClient.SqlTransaction

假设我是 using TransactionScope 但想将 SqlTransaction 传递给一些遗留代码。是否可以从TransactionScopeSqlConnection 获得Transaction

Using scope As TransactionScope = GetTransactionScope()
    Using conn As SqlClient.SqlConnection = GetConnection(Globals.ConnectionString)
        conn.Open()  'this will automatically enlist itself in a transaction if there is an ambient one created by `TransactionScope`

        LegacyFunction(transaction) '<-- how can I get the `transaction` here??

        ExecuteSQL(conn, sql, params)

        conn.Close()
    End Using

    scope.Complete()
End Using

【问题讨论】:

  • 为什么要在 Legacyfunction 中传递它??因为您的代码已经在 TransactionScope 块下运行。
  • 这是一个接受System.Data.SqlClient.SqlTransaction 作为参数的旧函数。我无法更改该功能,但我想使用TransactionScope。我想我可以使用System.Transactions.Current,但这不会返回System.Data.SqlClient.SqlTransaction
  • 大概你的 ExecuteSQL 做了一些涉及 SQLCommand 的事情?您是否查看过SqlCommand.Transaction Property 在入伍时是否已设置?

标签: .net sql-server vb.net


【解决方案1】:

我会尝试使用接受交易的 ctor

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();

    SqlCommand command = connection.CreateCommand();
    SqlTransaction transaction;

    // Start a local transaction.
    transaction = connection.BeginTransaction("SampleTransaction");

    // Must assign both transaction object and connection 
    // to Command object for a pending local transaction
    command.Connection = connection;
    command.Transaction = transaction;

    try
    {
        using (TransactionScope ts = New TransactionScope(transaction))
        {
            LegacyFunction(transaction);
            ....
        }
        transaction.Commit();
        Console.WriteLine("Commit");
    }
    catch (Exception ex)
    {
        Console.WriteLine("Commit Exception Type: {0}", ex.GetType());
        Console.WriteLine("  Message: {0}", ex.Message);

        // Attempt to roll back the transaction. 
        try
        {
            transaction.Rollback();
        }
        catch (Exception ex2)
        {
            // This catch block will handle any errors that may have occurred 
            // on the server that would cause the rollback to fail, such as 
            // a closed connection.
            Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType());
            Console.WriteLine("  Message: {0}", ex2.Message);
        }
    }
}

【讨论】:

  • TransactionScope 将 Transaction 作为参数,而不是 SqlTransaction
【解决方案2】:

除了 Blam 给出的答案之外,还有一件事是 - System.Transactions.TransactionScopeIDBTransaction 是完全不同的概念。因此,您可以在 Blam 的回答中看到 - 在 DbConnection 对象上调用 BeginTransaction 时,您可以通过不同的方法传递该事务对象。

简而言之,您不能在旧函数中使用 TransactionScope

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多