MSDTC Transaction Advances to Distribution by Request Executed Outside the Transaction Area

I have a SQL Server 2008 database with two tables, a .NET 4.5 application using TransactionScopetwo database queries, each of which uses its own separate connection, which shares a single connection string.

This code works fine:

internal static void Main(string[] args)
{
    string connStr = string.Format(
        "Data Source={0};Initial Catalog={1};" +
        "Integrated Security=True", "My DB Server", "My Database");

    using (var scope = new TransactionScope())
    {
        string query1 = "(actual query not relevant)";
        var ds = GetSqlServerDataSet(query1, connStr);
        string query2 = "(actual query not relevant)";
        var ds1 = GetSqlServerDataSet(query2, connStr);
        scope.Complete();
    }
}

private static System.Data.DataSet GetSqlServerDataSet(string usingQuery, 
    string usingConnectionString, 
    params System.Data.SqlClient.SqlParameter[] withParameters)
{
    using (var ds = new System.Data.DataSet())
    using (var conn = new System.Data.SqlClient.SqlConnection(usingConnectionString))
    using (var command = new System.Data.SqlClient.SqlCommand(usingQuery, conn))
    {
        command.Parameters.AddRange(withParameters);

        using (var adapter = new System.Data.SqlClient.SqlDataAdapter(command))
        {
            adapter.Fill(ds);
        }

        return ds;
    }
}

Now, if I make an exception inside the scope for checking the rollback, this is when things get weird. I am using the reference class library that I wrote to save information about exceptions from the database. This is the same type of setup - the same SQL Server, .NET version, identical ADO.NET code, etc. It is simply written to another database.

Here's how it works: I added this method to my application:

private static void HandleUnhandledException(Object sender, System.UnhandledExceptionEventArgs e)
{
    ExceptionHandling.Core.Main.ProcessException((Exception) e.ExceptionObject);
    Environment.Exit(0);
}

Main:

AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException;

, , . throw new Exception("blah"); Main scope.Complete(), HandleUnhandledException, , . System.Transactions.TransactionManagerCommunicationException :

(MSDTC) . DTC MSDTC .

Connection.Open() .

, ? , , . ? , using , HandleUnhandledException, . ?

+4
1

, , HandleUnhandledException - using, finally . :

class Program {
    static void Main(string[] args) {
        AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
        try {
            throw new Exception("test");
        }
        finally {
            Console.WriteLine("finally");
        }
    }

    private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) {
        Console.WriteLine("handle exception");
    }
}

:

handle exception
Unhandled exception: System.Exception: test ...
finally

( , , ) . , - , .

, , , .

, , - , , ( , - ):

private static void HandleException(Exception ex) {
    TransactionScope scope = null;
    if (Transaction.Current != null)
        scope = new TransactionScope(TransactionScopeOption.Suppress);
    try {
        // do stuff
    }
    finally {
        scope?.Dispose();
    }
}

, , TransactionScope.

+4

Source: https://habr.com/ru/post/1676942/


All Articles