示例#1
0
        public void ParticipatingTransactionWithWithNotSupported()
        {
            IDbConnection   connection     = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
            ISessionFactory sessionFactory = (ISessionFactory)mocks.CreateMock(typeof(ISessionFactory));
            ISession        session        = (ISession)mocks.CreateMock(typeof(ISession));
            ITransaction    transaction    = (ITransaction)mocks.CreateMock(typeof(ITransaction));

            //using (mocks.Ordered())
            //{
            Expect.Call(sessionFactory.OpenSession()).Return(session).Repeat.Twice();
            Expect.Call(session.Connection).Return(connection);


            Expect.Call(session.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
            Expect.Call(session.IsOpen).Return(true);
            Expect.Call(session.FlushMode).Return(FlushMode.Auto).Repeat.Twice();
            session.Flush();
            LastCall.On(session).Repeat.Twice();
            transaction.Commit();
            LastCall.On(transaction).Repeat.Once();
#if NH_2_0
            Expect.Call(session.Close()).Return(null).Repeat.Once();
#else
            Expect.Call(session.Close()).Return(null).Repeat.Twice();
#endif
            //}
            mocks.ReplayAll();


            HibernateTransactionManager tm = new HibernateTransactionManager(sessionFactory);
            tm.TransactionSynchronization = TransactionSynchronizationState.Always;

            TransactionTemplate tt = new TransactionTemplate(tm);
            tt.PropagationBehavior = TransactionPropagation.RequiresNew;

            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");

            tt.Execute(new ParticipatingTransactionWithWithNotSupportedTxCallback(tt, sessionFactory));

            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");

            mocks.VerifyAll();
        }
示例#2
0
        /// <summary>The do get transaction.</summary>
        /// <returns>The System.Object.</returns>
        protected override object DoGetTransaction()
        {
            var            transaction = new ResourcelessTransaction();
            Stack <object> resources;

            if (!TransactionSynchronizationManager.HasResource(this))
            {
                resources = new Stack <object>();
                TransactionSynchronizationManager.BindResource(this, resources);
            }
            else
            {
                var stack = (Stack <object>)TransactionSynchronizationManager.GetResource(this);
                resources = stack;
            }

            resources.Push(transaction);
            return(transaction);
        }
示例#3
0
        public void TransactionRollbackOnly()
        {
            IDbConnection   connection     = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
            ISessionFactory sessionFactory = (ISessionFactory)mocks.CreateMock(typeof(ISessionFactory));
            ISession        session        = (ISession)mocks.CreateMock(typeof(ISession));
            ITransaction    transaction    = (ITransaction)mocks.CreateMock(typeof(ITransaction));
            IDbTransaction  adoTransaction = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));

            using (mocks.Ordered())
            {
                Expect.Call(sessionFactory.OpenSession()).Return(session);
                Expect.Call(session.Connection).Return(connection);
                Expect.Call(session.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
                Expect.Call(session.IsOpen).Return(true);
                Expect.Call(session.FlushMode).Return(FlushMode.Auto);
                session.Flush();
                LastCall.On(session).Repeat.Once();

                Expect.Call(adoTransaction.Connection).Return(connection);
                LastCall.On(adoTransaction).Repeat.Once();

                transaction.Rollback();
                LastCall.On(transaction).Repeat.Once();
                Expect.Call(session.Close()).Return(null);
            }
            mocks.ReplayAll();


            TestableHibernateTransactionManager tm = new TestableHibernateTransactionManager(sessionFactory);

            tm.TransactionSynchronization = TransactionSynchronizationState.Always;
            tm.StubbedTransactionThatReturnsExpectedConnection = adoTransaction;

            TransactionTemplate tt = new TransactionTemplate(tm);

            Assert.IsFalse(TransactionSynchronizationManager.HasResource(sessionFactory), "Shouldn't have a thread session");

            tt.Execute(new TransactionRollbackOnlyTxCallback(sessionFactory));

            Assert.IsFalse(TransactionSynchronizationManager.HasResource(sessionFactory), "Shouldn't have a thread session");

            mocks.VerifyAll();
        }
示例#4
0
        public void SingleSessionAppliesDefaultFlushModeOnOpenSessionAndClosesSession()
        {
            ISession expectedSession = Fake <ISession>();

            CallTo(() => expectedSessionFactory.OpenSession()).Returns(expectedSession);

            SessionScope scope = null;

            using (scope = new SessionScope(expectedSessionFactory, null, true, FlushMode.Auto, true))
            {
                SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.GetResource(expectedSessionFactory);
                Assert.IsTrue(sessionHolder.ContainsSession(expectedSession));
            }
            // ensure scope is closed and sessionHolder is unregistered from TSM
            Assert.IsFalse(scope.IsOpen);
            Assert.IsFalse(TransactionSynchronizationManager.HasResource(expectedSessionFactory));

            CallToSet(() => expectedSession.FlushMode).WhenArgumentsMatch(x => x.Get <FlushMode>(0) == FlushMode.Auto).MustHaveHappenedOnceExactly();
            CallTo(() => expectedSession.Close()).MustHaveHappenedOnceExactly();
        }
示例#5
0
        public void SingleSessionRegistersSessionHolderWithTSM()
        {
            SessionScope scope = null;

            using (scope = new SessionScope(expectedSessionFactory, null, true, FlushMode.Auto, true))
            {
                // ensure is open
                Assert.IsTrue(scope.IsOpen);
                Assert.IsFalse(scope.IsParticipating);

                // ensure registered sessionholder with TSM
                Assert.IsTrue(TransactionSynchronizationManager.HasResource(expectedSessionFactory));
                // ensure a sessionHolder is registered
                SessionHolder sessionHolder = TransactionSynchronizationManager.GetResource(expectedSessionFactory) as SessionHolder;
                Assert.IsNotNull(sessionHolder);
            }
            // ensure scope is closed and sessionHolder is unregistered from TSM
            Assert.IsFalse(scope.IsOpen);
            Assert.IsFalse(TransactionSynchronizationManager.HasResource(expectedSessionFactory));
        }
        public void TransactionRollback()
        {
            IDbProvider     provider       = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
            IDbConnection   connection     = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
            ISessionFactory sessionFactory = (ISessionFactory)mocks.CreateMock(typeof(ISessionFactory));
            ISession        session        = (ISession)mocks.CreateMock(typeof(ISession));
            ITransaction    transaction    = (ITransaction)mocks.CreateMock(typeof(ITransaction));

            using (mocks.Ordered())
            {
                Expect.Call(sessionFactory.OpenSession()).Return(session);
                Expect.Call(session.Connection).Return(connection);
                Expect.Call(session.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
                Expect.Call(session.IsOpen).Return(true);

                transaction.Rollback();
                LastCall.On(transaction).Repeat.Once();

                Expect.Call(session.Close()).Return(null);
            }
            mocks.ReplayAll();

            HibernateTransactionManager tm = new HibernateTransactionManager(sessionFactory);
            TransactionTemplate         tt = new TransactionTemplate(tm);

            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");
            Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");

            try
            {
                tt.Execute(new TransactionRollbackTxCallback(sessionFactory));
                Assert.Fail("Should have thrown exception");
            } catch (ArgumentException)
            {
            }

            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");
            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(provider), "Hasn't thread db provider");

            mocks.VerifyAll();
        }
示例#7
0
        public void TransactionWithPropagationSupports()
        {
            ISessionFactory sessionFactory = (ISessionFactory)mocks.CreateMock(typeof(ISessionFactory));
            ISession        session        = (ISession)mocks.CreateMock(typeof(ISession));

            Expect.Call(sessionFactory.OpenSession()).Return(session);
            Expect.Call(session.FlushMode).Return(FlushMode.Never);
            session.FlushMode = FlushMode.Auto;
            LastCall.IgnoreArguments();
            session.Flush();
            LastCall.IgnoreArguments();
            session.FlushMode = FlushMode.Never;
            Expect.Call(session.FlushMode).Return(FlushMode.Never);
#if NH_2_0
#else
            Expect.Call(session.Close()).Return(null);
#endif

            mocks.ReplayAll();


            LocalSessionFactoryObjectStub lsfo = new LocalSessionFactoryObjectStub(sessionFactory);
            lsfo.AfterPropertiesSet();
            ISessionFactory sfProxy = (ISessionFactory)lsfo.GetObject();
            Assert.IsNotNull(sfProxy);

            HibernateTransactionManager tm = new HibernateTransactionManager(sessionFactory);
            tm.TransactionSynchronization = TransactionSynchronizationState.Always;

            TransactionTemplate tt = new TransactionTemplate(tm);
            tt.PropagationBehavior = TransactionPropagation.Supports;

            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");

            tt.Execute(new TransactionWithPropagationSupportsTxCallback(sessionFactory));

            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");

            mocks.VerifyAll();
        }
示例#8
0
        public void ParticipatingTransactionWithWithRequiresNew()
        {
            DbConnection    connection     = A.Fake <DbConnection>();
            ISessionFactory sessionFactory = A.Fake <ISessionFactory>();
            ISession        session1       = A.Fake <ISession>();
            ISession        session2       = A.Fake <ISession>();
            ITransaction    transaction    = A.Fake <ITransaction>();

            A.CallTo(() => sessionFactory.OpenSession()).Returns(session1).Once()
            .Then.Returns(session2).Once();

            A.CallTo(() => session1.Connection).Returns(connection);
            A.CallTo(() => session1.BeginTransaction(IsolationLevel.ReadCommitted)).Returns(transaction);
            A.CallTo(() => session1.IsOpen).Returns(true);

            A.CallTo(() => session2.Connection).Returns(connection);
            A.CallTo(() => session2.BeginTransaction(IsolationLevel.ReadCommitted)).Returns(transaction);
            A.CallTo(() => session2.IsOpen).Returns(true);

            A.CallTo(() => session2.FlushMode).Returns(FlushMode.Auto);

            HibernateTransactionManager tm = new HibernateTransactionManager(sessionFactory);

            tm.TransactionSynchronization = TransactionSynchronizationState.Always;

            TransactionTemplate tt = new TransactionTemplate(tm);

            tt.PropagationBehavior = TransactionPropagation.RequiresNew;

            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");

            tt.Execute(new ParticipatingTransactionWithWithRequiresNewTxCallback(tt, sessionFactory));

            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");

            A.CallTo(() => transaction.Commit()).MustHaveHappenedTwiceExactly();
            A.CallTo(() => session2.Flush()).MustHaveHappenedOnceExactly();
            A.CallTo(() => session1.Close()).MustHaveHappenedOnceExactly();
            A.CallTo(() => session2.Close()).MustHaveHappenedOnceExactly();
        }
示例#9
0
        public void TransactionRollback()
        {
            IDbProvider     provider       = A.Fake <IDbProvider>();
            DbConnection    connection     = A.Fake <DbConnection>();
            ISessionFactory sessionFactory = A.Fake <ISessionFactory>();
            ISession        session        = A.Fake <ISession>();
            ITransaction    transaction    = A.Fake <ITransaction>();
            IDbTransaction  adoTransaction = A.Fake <IDbTransaction>();

            A.CallTo(() => sessionFactory.OpenSession()).Returns(session).Once();
            A.CallTo(() => session.Connection).Returns(connection).Once();
            A.CallTo(() => session.BeginTransaction(IsolationLevel.ReadCommitted)).Returns(transaction).Once();
            A.CallTo(() => session.IsOpen).Returns(true).Once();
            A.CallTo(() => adoTransaction.Connection).Returns(connection).Once();

            TestableHibernateTransactionManager tm = new TestableHibernateTransactionManager(sessionFactory);

            tm.TransactionSynchronization = TransactionSynchronizationState.Always;
            tm.StubbedTransactionThatReturnsExpectedConnection = adoTransaction;

            TransactionTemplate tt = new TransactionTemplate(tm);

            Assert.IsFalse(TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");
            Assert.IsFalse(TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");

            try
            {
                tt.Execute(new TransactionRollbackTxCallback(sessionFactory));
                Assert.Fail("Should have thrown exception");
            }
            catch (ArgumentException)
            {
            }

            Assert.IsFalse(TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");
            Assert.IsFalse(TransactionSynchronizationManager.HasResource(provider), "Hasn't thread db provider");

            A.CallTo(() => transaction.Rollback()).MustHaveHappened();
            A.CallTo(() => session.Close()).MustHaveHappened();
        }
示例#10
0
        public void SingleSessionAppliesDefaultFlushModeOnOpenSessionAndClosesSession()
        {
            ISession expectedSession = mocks.StrictMock <ISession>();

            Expect.Call(expectedSessionFactory.OpenSession()).Return(expectedSession);
            expectedSession.FlushMode = FlushMode.Auto;
            Expect.Call(expectedSession.Close()).Return(null);
            mocks.ReplayAll();

            SessionScope scope = null;

            using (scope = new SessionScope(expectedSessionFactory, null, true, FlushMode.Auto, true))
            {
                SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.GetResource(expectedSessionFactory);
                Assert.IsTrue(sessionHolder.ContainsSession(expectedSession));
            }
            // ensure scope is closed and sessionHolder is unregistered from TSM
            Assert.IsFalse(scope.IsOpen);
            Assert.IsFalse(TransactionSynchronizationManager.HasResource(expectedSessionFactory));

            mocks.VerifyAll();
        }
示例#11
0
        /// <summary>
        /// Return the current transaction object.
        /// </summary>
        /// <returns>The current transaction object.</returns>
        /// <exception cref="Spring.Transaction.CannotCreateTransactionException">
        /// If transaction support is not available.
        /// </exception>
        /// <exception cref="Spring.Transaction.TransactionException">
        /// In the case of lookup or system errors.
        /// </exception>
        protected override object DoGetTransaction()
        {
            HibernateTransactionObject txObject = new HibernateTransactionObject();

            txObject.SavepointAllowed = NestedTransactionsAllowed;
            if (TransactionSynchronizationManager.HasResource(SessionFactory))
            {
                SessionHolder sessionHolder =
                    (SessionHolder)TransactionSynchronizationManager.GetResource(SessionFactory);
                if (log.IsDebugEnabled)
                {
                    log.Debug("Found thread-bound Session [" + sessionHolder.Session +
                              "] for Hibernate transaction");
                }
                txObject.SetSessionHolder(sessionHolder, false);
                if (DbProvider != null)
                {
                    ConnectionHolder conHolder = (ConnectionHolder)
                                                 TransactionSynchronizationManager.GetResource(DbProvider);
                    txObject.ConnectionHolder = conHolder;
                }
            }
            return(txObject);
        }
示例#12
0
        public void TransactionCommit()
        {
            IDbProvider     provider       = (IDbProvider)mocks.CreateMock(typeof(IDbProvider));
            IDbConnection   connection     = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
            ISessionFactory sessionFactory = (ISessionFactory)mocks.CreateMock(typeof(ISessionFactory));
            ISession        session        = (ISession)mocks.CreateMock(typeof(ISession));
            ITransaction    transaction    = (ITransaction)mocks.CreateMock(typeof(ITransaction));
            IQuery          query          = (IQuery)mocks.CreateMock(typeof(IQuery));

            IList list = new ArrayList();

            list.Add("test");
            using (mocks.Ordered())
            {
                Expect.Call(sessionFactory.OpenSession()).Return(session);
                Expect.Call(session.Connection).Return(connection);
                Expect.Call(session.BeginTransaction(IsolationLevel.Serializable)).Return(transaction);
                Expect.Call(session.IsOpen).Return(true);
                Expect.Call(session.CreateQuery("some query string")).Return(query);
                Expect.Call(query.List()).Return(list);
                transaction.Commit();
                LastCall.On(transaction).Repeat.Once();
                Expect.Call(session.Close()).Return(null);
            }

            mocks.ReplayAll();


            LocalSessionFactoryObjectStub lsfo = new LocalSessionFactoryObjectStub(sessionFactory);

            lsfo.AfterPropertiesSet();

            ISessionFactory sfProxy = lsfo.GetObject() as ISessionFactory;

            Assert.IsNotNull(sfProxy);

            HibernateTransactionManager tm = new HibernateTransactionManager();

            tm.TransactionSynchronization = TransactionSynchronizationState.Always;
            tm.AdoExceptionTranslator     = new FallbackExceptionTranslator();
            tm.SessionFactory             = sfProxy;
            tm.DbProvider = provider;
            TransactionTemplate tt = new TransactionTemplate(tm);

            tt.TransactionIsolationLevel = IsolationLevel.Serializable;

            Assert.IsFalse(TransactionSynchronizationManager.HasResource(sfProxy), "Hasn't thread session");
            Assert.IsFalse(TransactionSynchronizationManager.HasResource(provider), "Hasn't thread db provider");
            Assert.IsFalse(TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
            Assert.IsFalse(TransactionSynchronizationManager.ActualTransactionActive, "Actual transaction not active");

            object result = tt.Execute(new TransactionCommitTxCallback(sfProxy, provider));

            Assert.IsTrue(result == list, "Incorrect result list");

            Assert.IsFalse(TransactionSynchronizationManager.HasResource(sfProxy), "Hasn't thread session");
            Assert.IsFalse(TransactionSynchronizationManager.HasResource(provider), "Hasn't thread db provider");
            Assert.IsFalse(TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");
            Assert.IsFalse(TransactionSynchronizationManager.ActualTransactionActive, "Actual transaction not active");


            mocks.VerifyAll();
        }
示例#13
0
        /// <summary>
        /// Does the test transaction commit with flush failure.
        /// </summary>
        /// <param name="fallbackTranslation">if set to <c>true</c> if the exception throw
        /// is of the type NHibernate.ADOException, in which case HibernateTransactionManager
        /// will 'fallback' to using the error codes in the underlying exception thrown by
        /// the provider, ie. a SqlException, MySqlException.  Otherwise, if it is
        /// another subclass of HibernateException, then perform a direct maping as
        /// found in SessionFactoryUtils.ConvertHibernateAccessException.</param>
        private void DoTransactionCommitWithFlushFailure(bool fallbackTranslation)
        {
            #region Mock Setup

            IDbProvider     provider       = new TestDbProvider();
            IDbConnection   connection     = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
            ISessionFactory sessionFactory = (ISessionFactory)mocks.CreateMock(typeof(ISessionFactory));
            ISession        session        = (ISession)mocks.CreateMock(typeof(ISession));
            ITransaction    transaction    = (ITransaction)mocks.CreateMock(typeof(ITransaction));
            IDbTransaction  adoTransaction = (IDbTransaction)mocks.CreateMock(typeof(IDbTransaction));

            Exception rootCause = null;
            using (mocks.Ordered())
            {
                Expect.Call(sessionFactory.OpenSession()).Return(session);
                Expect.Call(session.Connection).Return(connection);
                Expect.Call(session.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
                Expect.Call(session.IsOpen).Return(true);
                transaction.Commit();
                Exception sqlException = new TestSqlException("mymsg", "2627");
                if (fallbackTranslation)
                {
                    //error code 2627 will map to a DataAccessIntegrity exception in sqlserver, which is the metadata
                    //used by TestDbProvider.
                    rootCause = sqlException;
                    LastCall.On(transaction).Throw(new ADOException("mymsg", sqlException));
                }
                else
                {
#if NH_2_0 || NH_2_1
                    rootCause = new PropertyValueException("mymsg", typeof(string).Name, "Name");
#else
                    rootCause = new PropertyValueException("mymsg", typeof(string), "Name");
#endif
                    LastCall.On(transaction).Throw(rootCause);
                }

                Expect.Call(adoTransaction.Connection).Return(connection);
                LastCall.On(adoTransaction).Repeat.Once();

                transaction.Rollback();
                LastCall.On(transaction).Repeat.Once();
                Expect.Call(session.Close()).Return(null);
            }

            #endregion

            mocks.ReplayAll();


            TestableHibernateTransactionManager tm = new TestableHibernateTransactionManager(sessionFactory);
            tm.TransactionSynchronization = TransactionSynchronizationState.Always;
            tm.DbProvider = provider;
            tm.StubbedTransactionThatReturnsExpectedConnection = adoTransaction;

            TransactionTemplate tt = new TransactionTemplate(tm);
            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");
            Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");

            IList list = new ArrayList();
            list.Add("test");
            try
            {
                tt.Execute(new TransactionCommitWithFlushFailureCallback(sessionFactory, list));
                Assert.Fail("Should have thrown DataIntegrityViolationException");
            }
            catch (DataIntegrityViolationException ex)
            {
                Assert.AreEqual(rootCause, ex.InnerException);
                Assert.IsTrue(ex.Message.IndexOf("mymsg") != -1);
            }

            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");
            Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");

            mocks.VerifyAll();
        }
示例#14
0
        public void TransactionWithPropagationSupportsAndInnerTransaction()
        {
            IDbConnection   connection     = (IDbConnection)mocks.CreateMock(typeof(IDbConnection));
            ISessionFactory sessionFactory = (ISessionFactory)mocks.CreateMock(typeof(ISessionFactory));
            ISession        session1       = (ISession)mocks.CreateMock(typeof(ISession));
            ISession        session2       = (ISession)mocks.CreateMock(typeof(ISession));
            ITransaction    transaction    = (ITransaction)mocks.CreateMock(typeof(ITransaction));

            Expect.Call(sessionFactory.OpenSession()).Return(session1);
            Expect.Call(session1.Connection).Return(connection);
            Expect.Call(session1.SessionFactory).Return(sessionFactory);
            Expect.Call(session1.FlushMode).Return(FlushMode.Auto).Repeat.Twice();

            session1.Flush();
            LastCall.IgnoreArguments().Repeat.Twice();
            Expect.Call(session1.Close()).Return(null);

            Expect.Call(sessionFactory.OpenSession()).Return(session2);
            Expect.Call(session2.Connection).Return(connection).Repeat.Twice();
            Expect.Call(session2.BeginTransaction(IsolationLevel.ReadCommitted)).Return(transaction);
            Expect.Call(session2.FlushMode).Return(FlushMode.Auto);
            session2.Flush();
            LastCall.IgnoreArguments();
            Expect.Call(session2.IsOpen).Return(true);


            transaction.Commit();
            LastCall.On(transaction).Repeat.Once();


            Expect.Call(session2.Close()).Return(null);

            mocks.ReplayAll();

            LocalSessionFactoryObjectStub lsfo = new LocalSessionFactoryObjectStub(sessionFactory);

            lsfo.AfterPropertiesSet();
            ISessionFactory sfProxy = (ISessionFactory)lsfo.GetObject();

            Assert.IsNotNull(sfProxy);

            HibernateTransactionManager tm = new HibernateTransactionManager(sessionFactory);

            tm.TransactionSynchronization = TransactionSynchronizationState.Always;

            TransactionTemplate tt = new TransactionTemplate(tm);

            tt.PropagationBehavior = TransactionPropagation.Supports;
            TransactionTemplate tt2 = new TransactionTemplate(tm);

            tt2.PropagationBehavior = TransactionPropagation.Required;

            HibernateTemplate ht = new HibernateTemplate(sessionFactory);

            ht.TemplateFlushMode   = TemplateFlushMode.Eager;
            ht.ExposeNativeSession = true;

            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");

            tt.Execute(new TransactionWithPropagationSupportsAndInnerTransactionTxCallback(tt2, sessionFactory, ht, session1, session2));

            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");

            mocks.ReplayAll();
        }
        /// <summary>
        /// Begin a new transaction with the given transaction definition.
        /// </summary>
        /// <param name="transaction">
        /// Transaction object returned by
        /// <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.DoGetTransaction"/>.
        /// </param>
        /// <param name="definition">
        /// <see cref="Spring.Transaction.ITransactionDefinition"/> instance, describing
        /// propagation behavior, isolation level, timeout etc.
        /// </param>
        /// <remarks>
        /// Does not have to care about applying the propagation behavior,
        /// as this has already been handled by this abstract manager.
        /// </remarks>
        /// <exception cref="Spring.Transaction.TransactionException">
        /// In the case of creation or system errors.
        /// </exception>
        protected override void DoBegin(object transaction, ITransactionDefinition definition)
        {
            TxScopeTransactionManager.PromotableTxScopeTransactionObject promotableTxScopeTransactionObject =
                ((HibernateTransactionObject)transaction).PromotableTxScopeTransactionObject;
            try
            {
                DoTxScopeBegin(promotableTxScopeTransactionObject, definition);
            }
            catch (Exception e)
            {
                throw new CannotCreateTransactionException("Transaction Scope failure on begin", e);
            }

            HibernateTransactionObject txObject = (HibernateTransactionObject)transaction;

            if (DbProvider != null && TransactionSynchronizationManager.HasResource(DbProvider) &&
                !txObject.ConnectionHolder.SynchronizedWithTransaction)
            {
                throw new IllegalTransactionStateException(
                          "Pre-bound ADO.NET Connection found - HibernateTransactionManager does not support " +
                          "running within AdoTransactionManager if told to manage the DbProvider itself. " +
                          "It is recommended to use a single HibernateTransactionManager for all transactions " +
                          "on a single DbProvider, no matter whether Hibernate or ADO.NET access.");
            }
            ISession session = null;

            try
            {
                if (txObject.SessionHolder == null || txObject.SessionHolder.SynchronizedWithTransaction)
                {
                    IInterceptor interceptor = EntityInterceptor;
                    ISession     newSession  = (interceptor != null ?
                                                SessionFactory.OpenSession(interceptor) : SessionFactory.OpenSession());

                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Opened new Session [" + newSession + "] for Hibernate transaction");
                    }
                    txObject.SetSessionHolder(new SessionHolder(newSession), true);
                }
                txObject.SessionHolder.SynchronizedWithTransaction = true;
                session = txObject.SessionHolder.Session;

                IDbConnection con = session.Connection;
                //TODO isolation level mgmt
                //IsolationLevel previousIsolationLevel =

                if (definition.ReadOnly && txObject.NewSessionHolder)
                {
                    // Just set to NEVER in case of a new Session for this transaction.
                    session.FlushMode = FlushMode.Never;
                }

                if (!definition.ReadOnly && !txObject.NewSessionHolder)
                {
                    // We need AUTO or COMMIT for a non-read-only transaction.
                    FlushMode flushMode = session.FlushMode;
                    if (FlushMode.Never == flushMode)
                    {
                        session.FlushMode = FlushMode.Auto;
                        txObject.SessionHolder.PreviousFlushMode = flushMode;
                    }
                }

                // Add the Hibernate transaction to the session holder.
                // for now pass in tx options isolation level.
                ITransaction   hibernateTx = session.BeginTransaction(definition.TransactionIsolationLevel);
                IDbTransaction adoTx       = GetIDbTransaction(hibernateTx);

                // Add the Hibernate transaction to the session holder.
                txObject.SessionHolder.Transaction = hibernateTx;

                // Register transaction timeout.
                int timeout = DetermineTimeout(definition);
                if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT)
                {
                    txObject.SessionHolder.TimeoutInSeconds = timeout;
                }

                // Register the Hibernate Session's ADO.NET Connection/TX pair for the DbProvider, if set.
                if (DbProvider != null)
                {
                    //investigate passing null for tx.
                    ConnectionHolder conHolder = new ConnectionHolder(con, adoTx);
                    if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT)
                    {
                        conHolder.TimeoutInMillis = definition.TransactionTimeout;
                    }
                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Exposing Hibernate transaction as ADO transaction [" + con + "]");
                    }
                    TransactionSynchronizationManager.BindResource(DbProvider, conHolder);
                    txObject.ConnectionHolder = conHolder;
                }

                // Bind the session holder to the thread.
                if (txObject.NewSessionHolder)
                {
                    TransactionSynchronizationManager.BindResource(SessionFactory, txObject.SessionHolder);
                }
            }
            catch (Exception ex)
            {
                SessionFactoryUtils.CloseSession(session);
                throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex);
            }
        }
示例#16
0
        /// <summary>
        /// Does the test transaction commit with flush failure.
        /// </summary>
        /// <param name="fallbackTranslation">if set to <c>true</c> if the exception throw
        /// is of the type NHibernate.ADOException, in which case HibernateTransactionManager
        /// will 'fallback' to using the error codes in the underlying exception thrown by
        /// the provider, ie. a SqlException, MySqlException.  Otherwise, if it is
        /// another subclass of HibernateException, then perform a direct maping as
        /// found in SessionFactoryUtils.ConvertHibernateAccessException.</param>
        private void DoTransactionCommitWithFlushFailure(bool fallbackTranslation)
        {
            IDbProvider     provider       = new TestDbProvider();
            DbConnection    connection     = A.Fake <DbConnection>();
            ISessionFactory sessionFactory = A.Fake <ISessionFactory>();
            ISession        session        = A.Fake <ISession>();
            ITransaction    transaction    = A.Fake <ITransaction>();
            IDbTransaction  adoTransaction = A.Fake <IDbTransaction>();

            Exception rootCause;

            A.CallTo(() => sessionFactory.OpenSession()).Returns(session);
            A.CallTo(() => session.Connection).Returns(connection);
            A.CallTo(() => session.BeginTransaction(IsolationLevel.ReadCommitted)).Returns(transaction);
            A.CallTo(() => session.IsOpen).Returns(true);
            Exception sqlException = new TestSqlException("mymsg", "2627");

            if (fallbackTranslation)
            {
                //error code 2627 will map to a DataAccessIntegrity exception in sqlserver, which is the metadata
                //used by TestDbProvider.
                rootCause = sqlException;
                A.CallTo(() => transaction.Commit()).Throws(new ADOException("mymsg", sqlException));
            }
            else
            {
                rootCause = new PropertyValueException("mymsg", typeof(string).Name, "Name");
                A.CallTo(() => transaction.Commit()).Throws(rootCause);
            }

            A.CallTo(() => adoTransaction.Connection).Returns(connection).Once();

            TestableHibernateTransactionManager tm = new TestableHibernateTransactionManager(sessionFactory);

            tm.TransactionSynchronization = TransactionSynchronizationState.Always;
            tm.DbProvider = provider;
            tm.StubbedTransactionThatReturnsExpectedConnection = adoTransaction;

            TransactionTemplate tt = new TransactionTemplate(tm);

            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");
            Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");

            IList list = new ArrayList();

            list.Add("test");
            try
            {
                tt.Execute(new TransactionCommitWithFlushFailureCallback(sessionFactory, list));
                Assert.Fail("Should have thrown DataIntegrityViolationException");
            }
            catch (DataIntegrityViolationException ex)
            {
                Assert.AreEqual(rootCause, ex.InnerException);
                Assert.IsTrue(ex.Message.IndexOf("mymsg") != -1);
            }

            Assert.IsTrue(!TransactionSynchronizationManager.HasResource(sessionFactory), "Hasn't thread session");
            Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");

            A.CallTo(() => transaction.Rollback()).MustHaveHappenedOnceExactly();
            A.CallTo(() => session.Close()).MustHaveHappenedOnceExactly();
        }