Transaction Scope exception in a simple scenario

Discussion of open issues, suggestions and bugs regarding Entity Framework support in ADO.NET Data providers
Post Reply
robymes
Posts: 29
Joined: Tue 09 Sep 2008 09:46

Transaction Scope exception in a simple scenario

Post by robymes » Wed 11 Feb 2009 22:33

Hello,
I'm starting to think that TransactionScope has some problem with dotConnect for Oracle 5.00.20.
I have a very simple test in which I read an object and insert another one with the same description:

Code: Select all

        [TestMethod]
        public void TransactionScopeWithSimpleInsert()
        {
            try
            {
                using (TransactionScope ts = new TransactionScope())
                {
                    TSObjectContext context = null;
                    try
                    {
                        context = new TSObjectContext();
                        TestData testData =
                            context.TestDataSet
                            .First();
                        Guid id = Guid.NewGuid();
                        TestData newTestData = TestData.CreateTestData(id);
                        newTestData.Description = testData.Description;
                        context.AddToTestDataSet(newTestData);
                        context.SaveChanges();
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                    finally
                    {
                        if (context != null)
                        {
                            context.Dispose();
                        }
                    }                    
                    ts.Complete();
                }                
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.Message);
            }
        }
this test throw an exception on ts.Complete():
The operation is not valid for the current state of the enlistment.

System.InvalidOperationException
at System.Transactions.EnlistmentState.ForceRollback(InternalEnlistment enlistment, Exception e)
at System.Transactions.PreparingEnlistment.ForceRollback()
at Devart.Data.Oracle.h.a(PreparingEnlistment A_0)
at System.Transactions.VolatileEnlistmentPreparing.EnterState(InternalEnlistment enlistment)
at System.Transactions.VolatileEnlistmentActive.ChangeStatePreparing(InternalEnlistment enlistment)
at System.Transactions.TransactionStateVolatilePhase1.EnterState(InternalTransaction tx)
at System.Transactions.TransactionStatePhase0.EnterState(InternalTransaction tx)
at System.Transactions.TransactionStateActive.BeginCommit(InternalTransaction tx, Boolean asyncCommit, AsyncCallback asyncCallback, Object asyncState)
at System.Transactions.CommittableTransaction.Commit()
at System.Transactions.TransactionScope.InternalDispose()
at System.Transactions.TransactionScope.Dispose()
at TestDevArtTransatcionScope.TestSuite.TransactionScopeTestCase.TransactionScopeWithSimpleInsert()
the same test works without any problem with SQLServer, and honestly I don't see any reason why it shouldn't work.
Why it fails with Oracle?
This is a very simple test, am I wrong somewhere?

Thanks.

robymes
Posts: 29
Joined: Tue 09 Sep 2008 09:46

Post by robymes » Thu 12 Feb 2009 07:59

I have to make an update on what I say in the first post:
the exception is thrown not on ts.Complete(), but on disposing the TransactionScope.
The following test code do not use the "using" keyword and call the Dispose method:

Code: Select all

        [TestMethod]
        public void TransactionScopeWithSimpleInsert()
        {
            try
            {
                TransactionScope ts = null;
                try
                {
                    ts = new TransactionScope();
                    TSObjectContext context = null;
                    try
                    {
                        context = new TSObjectContext();
                        TestData testData =
                            context.TestDataSet
                            .First();
                        Guid id = Guid.NewGuid();
                        TestData newTestData = TestData.CreateTestData(id);
                        newTestData.Description = testData.Description;
                        context.AddToTestDataSet(newTestData);
                        context.SaveChanges();
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                    finally
                    {
                        if (context != null)
                        {
                            context.Dispose();
                        }
                    }
                    ts.Complete();
                }
                catch (Exception)
                {
                    throw;
                }
                finally
                {
                    if (ts != null)
                    {
                        ts.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.Message);
            }
        }
On ts.Dispose() the provider throws the exception I quoted in the first post. The same code (without using keyword) works fine in SQLServer.

Thanks.

AndreyR
Devart Team
Posts: 2919
Joined: Mon 07 Jul 2008 13:16

Post by AndreyR » Thu 12 Feb 2009 10:39

Thank you for the reprot, we have already fixed this problem. Look forward to the next build.

robymes
Posts: 29
Joined: Tue 09 Sep 2008 09:46

Post by robymes » Thu 12 Feb 2009 11:07

Thanks for the answer,
I'd like to know when will be available the next build: we have a great issue with this kind of problem and we need the new version as soon as possible.

Thanks

AndreyR
Devart Team
Posts: 2919
Joined: Mon 07 Jul 2008 13:16

Post by AndreyR » Tue 17 Feb 2009 12:58

The new build is available.

Post Reply