TransactionScope Prematurely Completed

前端 未结 7 851
[愿得一人]
[愿得一人] 2020-12-13 02:01

I have a block of code that runs within a TransactionScope and within this block of code I make several calls to the DB. Selects, Updates, Creates, and Deletes, the whole ga

相关标签:
7条回答
  • 2020-12-13 02:28

    Don't forget to supress your select statements from your TransactionScope. In SQL Server 2005 and above, even when you use with(nolock), locks are still created on those tables the select touches. Check this out, it shows you how to setup and use TransactionScope.

    using(TransactionScope ts = new TransactionScope 
    { 
      // db calls here are in the transaction 
      using(TransactionScope tsSuppressed = new TransactionScope (TransactionScopeOption.Suppress)) 
      { 
        // all db calls here are now not in the transaction 
      } 
    } 
    
    0 讨论(0)
  • 2020-12-13 02:30

    If an exception happens inside a TransactionScope it is rolled back. This means that TransactionScope is done. You must now call dispose() on it and start a new transaction. I'm honestly not sure if you can reuse the old TransactionScope or not, I've never tried, but I'd assume not.

    0 讨论(0)
  • 2020-12-13 02:31

    I can reproduce the problem. It is a transaction timeout.

    using (new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 0, 1)))
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
            using (var sqlCommand = connection.CreateCommand())
            {
                for (int i = 0; i < 10000; i++)
                {
                    sqlCommand.CommandText = "select * from actor";
                    using (var sqlDataReader = sqlCommand.ExecuteReader())
                    {
                        while (sqlDataReader.Read())
                        {
                        }
                    }
                }
            }
        }
    }
    

    Throws System.InvalidOperationException with this message:

    The transaction associated with the current connection has completed but has not been disposed. The transaction must be disposed before the connection can be used to execute SQL statements.

    To solve the problem make your query run faster or increase the timeout.

    0 讨论(0)
  • 2020-12-13 02:37

    This exception can also be caused by disable Microsoft Distributed Transaction Coordinator.

    If we want enable it, we run "dcomcnfg" and select "Component Services" -> "My Computer" -> "Distributed Transaction Coordinator" -> "Local Service DTC" and choose "Properties".

    It should be checked "Allow Remote Client", "Allow Inbound", "Allow Outbound" and "No Authentication Required".

    0 讨论(0)
  • 2020-12-13 02:46

    I've found that this message can occur when a transaction runs for a longer period than the maxTimeout for System.Transactions. It doesn't matter that TransactionOptions.Timeout is increased, it can't exceed maxTimeout.

    The default value of maxTimeout is set to 10 minutes and its value can only be modified in the machine.config

    Add the following (in the configuration level) to the machine.config to modify the timeout:

    <configuration>
        <system.transactions>
            <machineSettings maxTimeout="00:30:00" />
        </system.transactions>
    </configuration>
    

    The machine.config can be found at: %windir%\Microsoft.NET\Framework\[version]\config\machine.config

    You can read more about it in this blog post: http://thecodesaysitall.blogspot.se/2012/04/long-running-systemtransactions.html

    0 讨论(0)
  • 2020-12-13 02:46

    My issue was a stupid one, if you sit on a debug break through the timeout you will get this. Face Palm

    Man, programming makes you feel thick some days...

    0 讨论(0)
提交回复
热议问题