简体   繁体   中英

Error: The underlying provider failed on Open. How to resolve it?

I have function that with code similar to this:

using(var db = new MyDbContext())
{
    //a whole bunch of code, db is working.

    //then I try opening another DbContext like so
    using(var dba = new AnotherDbContext())
    {
        //about 2 lines of code just to get something from a database
    }
}

And then I get 2 error messages when I get to the second DbContext:

"The underlying provider failed on Open." & "MSDTC on server 'myserver' is unavailable."

Does anybody know the reason why this is happening? Can I open 2 DbContexts at once?

In the first scenario, you are nesting AnotherDbContext . A connection to the database is opened for each on of them. When you call your service method within the using block, a new connection is opened within the MyDbContextwhile there is another one already open. This causes your transaction to be promoted to a distributed transaction, and partially committed data (the result of the dba.SaveChanges call in the service) not being available from your outer connection.Also note that distributed transactions are far slower and thus, this has the side effect of degrading performance.

private void btnTwoConnectionsNested_Click(object sender, EventArgs e)
{
    string connectionString = @"Data Source=" + tbServer.Text
        + @";Initial Catalog=master;Integrated Security=True; timeout=0";

    using (TransactionScope transactionScope = new TransactionScope())
    {
        SqlConnection connectionOne = new SqlConnection(connectionString);
        SqlConnection connectionTwo = new SqlConnection(connectionString);

        try
        {
            //2 connections, nested
            connectionOne.Open();
            connectionTwo.Open(); // escalates to DTC on 05 and 08
            connectionTwo.Close();
            connectionOne.Close();

            MessageBox.Show("Success");
        }
        catch (Exception ex)
        {
            MessageBox.Show("ERROR: " + ex.Message);
        }
        finally
        {
            connectionOne.Dispose();
            connectionTwo.Dispose();
        }
    }
}

Within one Transaction Scope, it will open two connections, nested. The result:

Against SQL Server 2005 Instance: MSDTC on server 'SERVERNAME' is unavailable.

Against SQL Server 2008 Instance:
MSDTC on server 'SERVERNAME' is unavailable.

SQL Server does, and should, escalate to DTC for a nested connection in both versions.

Nested connections will escalate to DTC in SQL Server 2005 and 2008. Opening one connection at a time will escalate to DTC in 2005, but WILL NOT in 2008.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM