Nested TransactionScope

Discussion of open issues, suggestions and bugs regarding Entity Framework support in ADO.NET Data providers
Post Reply
cdsys
Posts: 2
Joined: Thu 30 Jul 2009 11:14
Location: Belgium

Nested TransactionScope

Post by cdsys » Fri 23 Sep 2011 12:18

I'm have a case where I want to be able to nest TransactionScope with dotConnect for Oracle.

Code: Select all

        [TestMethod()]
        public void MicrosoftTransactieScenario4Test()
        {
            ClearTable();
            using (System.Transactions.TransactionScope ts = new System.Transactions.TransactionScope())
            {
                EntityConnection connection = new EntityConnection("name=TestModelContainer");
                TestModelContainer ent = new TestModelContainer(connection);
                var query = from t in ent.TEST_ALACOU_BAR_TPB_APP
                            where t.APP_CODE == "MYAPP"
                            select t;
                Assert.IsTrue(query.Count() == 0);
                // Create
                TEST_ALACOU_BAR_TPB_APP testEnt = new TEST_ALACOU_BAR_TPB_APP();
                testEnt.APP_ID = 1;
                testEnt.APP_CODE = "MYAPP";
                testEnt.ENVIRONMENT = "DEV";
                testEnt.APP_NAME = "MyOnlyApp";
                testEnt.APP_TYPE = "GUI";
                ent.AddToTEST_ALACOU_BAR_TPB_APP(testEnt);
                ent.SaveChanges();
                // Read
                Assert.IsTrue(query.Count() == 1);
                // Update
                testEnt.APP_NAME = "MyOnlyApp2";
                ent.SaveChanges();
                using (System.Transactions.TransactionScope ts2 = new System.Transactions.TransactionScope()) // System.Transactions.TransactionScopeOption.RequiresNew
                {
                    Assert.IsTrue(query.Count() == 1);
                    Assert.IsTrue(query.First().APP_NAME == "MyOnlyApp2");
                    // Update
                    testEnt.APP_NAME = "MyOnlyApp3333";
                    ent.SaveChanges();
                    Assert.IsTrue(query.First().APP_NAME == "MyOnlyApp3333");
                }
                // Read
                Assert.IsTrue(query.Count() == 1); // the test fails on this line...
                Assert.IsTrue(query.First().APP_NAME == "MyOnlyApp2");
                ts.Complete();
            }
        }
The test fails at the line indicated by the comment with following exception:

Error message:
Test method Domain.BasisArchitectuur.TestEf.BarObjectContextTest.MicrosoftTransactieScenario4Test threw exception:
System.Data.EntityException: The underlying provider failed on Open. ---> System.Transactions.TransactionException: The operation is not valid for the state of the transaction.

Error stack:
System.Transactions.TransactionState.EnlistVolatile(InternalTransaction tx, IEnlistmentNotification enlistmentNotification, EnlistmentOptions enlistmentOptions, Transaction atomicTransaction)
System.Transactions.Transaction.EnlistVolatile(IEnlistmentNotification enlistmentNotification, EnlistmentOptions enlistmentOptions)
Devart.Common.DbConnectionInternal.EnlistToDistributedTransactionInternal(Transaction transaction)
Devart.Common.DbConnectionInternal.c()
Devart.Common.DbConnectionFactory.a(DbConnectionBase A_0)
Devart.Common.DbConnectionClosed.Open(DbConnectionBase outerConnection)
Devart.Common.DbConnectionBase.Open()
Devart.Data.Oracle.OracleConnection.Open()
System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
System.Data.EntityClient.EntityConnection.Open()
System.Data.Objects.ObjectContext.EnsureConnection()
System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable.GetEnumerator()
System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
System.Data.Objects.ELinq.ObjectQueryProvider.b__3[TResult](IEnumerable`1 sequence)
System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression)
System.Linq.Queryable.Count[TSource](IQueryable`1 source)
TestEf.BarObjectContextTest.MicrosoftTransactieScenario4Test() in C:\Projects\TestEf\ObjectContextTest.cs: line 713

It looks like the connection was closed after leaving the inner scope. I was hoping that the connection and transaction would stay open on the databaselevel (using savepoints for the innertransactions).

Any suggestions?

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Post by Shalex » Mon 26 Sep 2011 10:50

Could you please send us a small complete test project (with your model and DDL/DML script) so that we can reproduce the issue in our environment?

Shalex
Site Admin
Posts: 9543
Joined: Thu 14 Aug 2008 12:44

Post by Shalex » Wed 05 Oct 2011 09:41

Please call ts2.Complete() for the nested transaction.

Post Reply