3

I am having a problem in a production environment that I am not getting locally.

I am running some LINQ to SQL code within a TransactionScope as below:

        using (var scope = new TransactionScope())
        {
            uploadRepository.SubmitChanges();
            result = SubmitFileResult.Succeed();

            ScanForNewData(upload);

            scope.Complete();
        }

ScanForNewData() calls GetSubmittedData(). If an exception occurs in GetSubmitted() we use Nlog to write the error to file, database and also send an email:

        catch (Exception ex)
        {
            //MT - having to comment this out beause it is causing a problem with transactions on theproduction server
            logger.ErrorException(String.Format("Error reading txt file {0} into correct format", upload.DocumentStore.FileName), ex);
            return new UploadGetSubmittedDataResult { Exception = ex, Success = false, Message = String.Format("Error reading txt file {0} into correct format", upload.DocumentStore.FileName) };
        }

In ScanForNewData we then call repository.SubmitChanges().This then causes:

The operation is not valid for the state of the transaction. System.Transactions.TransactionException TransactionException System.Transactions.TransactionException: The operation is not valid for the state of the transaction.

The best idea I have come up with is that in production this code is running on a web server and calling a separate database server. Both the DataContext and Nlog have the same connectionstring configuration and Sql user, but maybe because the server is remote (whereas locally I am using integrated security) something strange is happening.

Any idea what happens to the transaction in this scenario?

Update - I just tried it with SQL user locally and it still works fine. Must be something to do with the production set up...

Another update - I tell a lie. On the dev maching the Nlog database record is never written, the email is sent, and the TransactionException does not happen.

MT.
  • 791
  • 5
  • 15
  • 23
  • may help http://stackoverflow.com/questions/2884863/under-what-circumstances-is-an-sqlconnection-automatically-enlisted-in-an-ambien – Joe Jun 05 '12 at 17:44

3 Answers3

0

Hard to guess what is the problem without a full stack trace of the exception, it may depend on multiple things.

For instance, I'm assuming NLog opens a new connection to the db my himself, and that will probably cause the transaction to be promoted to a distributed one, and the Distributed Transaction Coordinator will kick in. This can cause the asymmetry between the behavior of your application in production and locally.

You may be breaking the transaction with some operation inside it, like some unhandled exception or illegal accessing of some data.

Provide full stack trace and more code involved for a deeper analysis.

WDRust
  • 3,663
  • 1
  • 19
  • 23
0

Without knowing what the inner exceptions off of your TransactionException is it will be difficult to resolve but here is a thought:

If you refactor your code to have the logging occur after the using block around the transaction scope has ended you will likely avoid the issue you are having since the transaction scope will be ended and DTC will roll back the transaction.

I have used and seen this pattern in the past (don't log until after the transaction is ended and rolled back) when dealing with transactions and it has worked well.

Doing logging on a separate database is always advisable to avoid issues like this as well. If you did this the issue would also be avoided.

John Culviner
  • 22,235
  • 6
  • 55
  • 51
0

Have a look at this..seems to be a bug with Nlog.

https://groups.google.com/forum/#!msg/nlog-users/I5UR-bISlTA/6RPtOZhR4NoJ

suggested solution is to use async target for Db logging.