Пример #1
0
        public void Rollback()
        {
            ITransactionSynchronization sync =
                (ITransactionSynchronization)mocks.DynamicMock(typeof(ITransactionSynchronization));

            sync.BeforeCompletion();
            LastCall.On(sync).Repeat.Once();
            sync.AfterCompletion(TransactionSynchronizationStatus.Rolledback);
            LastCall.On(sync).Repeat.Once();
            mocks.ReplayAll();


            TxScopeTransactionManager tm = new TxScopeTransactionManager();
            TransactionTemplate       tt = new TransactionTemplate(tm);

            tt.TransactionTimeout = 10;
            tt.Name = "txName";

            Assert.IsFalse(TransactionSynchronizationManager.SynchronizationActive);
            Assert.IsNull(TransactionSynchronizationManager.CurrentTransactionName);
            Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
            tt.Execute(delegate(ITransactionStatus status)
            {
                Assert.IsTrue(TransactionSynchronizationManager.SynchronizationActive);
                TransactionSynchronizationManager.RegisterSynchronization(sync);
                Assert.AreEqual("txName", TransactionSynchronizationManager.CurrentTransactionName);
                Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
                status.SetRollbackOnly();
                return(null);
            }
                       );

            mocks.VerifyAll();
        }
Пример #2
0
        public void Rollback()
        {
            ITransactionSynchronization sync = A.Fake <ITransactionSynchronization>();

            TxScopeTransactionManager tm = new TxScopeTransactionManager();

            tm.TransactionSynchronization = TransactionSynchronizationState.Always;

            TransactionTemplate tt = new TransactionTemplate(tm);

            tt.TransactionTimeout = 10;
            tt.Name = "txName";

            Assert.IsFalse(TransactionSynchronizationManager.SynchronizationActive);
            Assert.IsNull(TransactionSynchronizationManager.CurrentTransactionName);
            Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
            tt.Execute(status =>
            {
                Assert.IsTrue(TransactionSynchronizationManager.SynchronizationActive);
                TransactionSynchronizationManager.RegisterSynchronization(sync);
                Assert.AreEqual("txName", TransactionSynchronizationManager.CurrentTransactionName);
                Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);
                status.SetRollbackOnly();
                return(null);
            }
                       );

            A.CallTo(() => sync.BeforeCompletion()).MustHaveHappenedOnceExactly();
            A.CallTo(() => sync.AfterCompletion(TransactionSynchronizationStatus.Rolledback)).MustHaveHappenedOnceExactly();
        }
Пример #3
0
        /// <summary>
        /// Get a ADO.NET Connection/Transaction Pair for the given IDbProvider.
        /// Same as <see cref="GetConnection"/> but throwing original provider
        /// exception.
        /// </summary>
        /// <remarks>
        /// Is aware of a corresponding Connection/Transaction bound to the current thread, for example
        /// when using AdoPlatformTransactionManager. Will bind a IDbConnection to the thread
        /// if transaction synchronization is active
        /// </remarks>
        /// <param name="provider">The provider.</param>
        /// <returns></returns>
        public static ConnectionTxPair DoGetConnection(IDbProvider provider)
        {
            AssertUtils.ArgumentNotNull(provider, "provider");
            ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.GetResource(provider);

            if (conHolder != null && (conHolder.HasConnection || conHolder.SynchronizedWithTransaction))
            {
                conHolder.Requested();
                if (!conHolder.HasConnection)
                {
                    if (LOG.IsDebugEnabled)
                    {
                        LOG.Debug("Fetching resumed ADO.NET connection from DbProvider");
                    }
                    conHolder.Connection = provider.CreateConnection();
                }
                return(new ConnectionTxPair(conHolder.Connection, conHolder.Transaction));
            }

            // Else we either got no holder or an empty thread-bound holder here.
            if (LOG.IsDebugEnabled)
            {
                LOG.Debug("Fetching Connection from DbProvider");
            }
            IDbConnection conn = provider.CreateConnection();

            conn.Open();

            if (TransactionSynchronizationManager.SynchronizationActive)
            {
                LOG.Debug("Registering transaction synchronization for IDbConnection");
                //Use same connection for further ADO.NET actions with the transaction.
                //Thread-bound object will get removed by manager at transaction completion.

                ConnectionHolder holderToUse = conHolder;
                if (holderToUse == null)
                {
                    holderToUse = new ConnectionHolder(conn, null);
                }
                else
                {
                    holderToUse.Connection = conn;
                }
                holderToUse.Requested();
                TransactionSynchronizationManager.RegisterSynchronization(
                    new ConnectionSynchronization(holderToUse, provider));
                holderToUse.SynchronizedWithTransaction = true;
                if (holderToUse != conHolder)
                {
                    TransactionSynchronizationManager.BindResource(provider, holderToUse);
                }
            }
            return(new ConnectionTxPair(conn, null));
        }
        /// <summary>Bind a resource to a transaction.</summary>
        /// <param name="resourceHolder">The resource holder.</param>
        /// <param name="connectionFactory">The connection factory.</param>
        /// <param name="synched">The synched.</param>
        public static void BindResourceToTransaction(RabbitResourceHolder resourceHolder, IConnectionFactory connectionFactory, bool synched)
        {
            if (TransactionSynchronizationManager.HasResource(connectionFactory) || !TransactionSynchronizationManager.ActualTransactionActive || !synched)
            {
                return;
            }

            TransactionSynchronizationManager.BindResource(connectionFactory, resourceHolder);
            resourceHolder.SynchronizedWithTransaction = true;
            if (TransactionSynchronizationManager.SynchronizationActive)
            {
                TransactionSynchronizationManager.RegisterSynchronization(new RabbitResourceSynchronization(resourceHolder, connectionFactory, synched));
            }
        }
Пример #5
0
        public static RabbitResourceHolder BindResourceToTransaction(RabbitResourceHolder resourceHolder, IConnectionFactory connectionFactory, bool synched)
        {
            if (TransactionSynchronizationManager.HasResource(connectionFactory) || !TransactionSynchronizationManager.IsActualTransactionActive() || !synched)
            {
                return((RabbitResourceHolder)TransactionSynchronizationManager.GetResource(connectionFactory)); // NOSONAR never null
            }

            TransactionSynchronizationManager.BindResource(connectionFactory, resourceHolder);
            resourceHolder.SynchronizedWithTransaction = true;
            if (TransactionSynchronizationManager.IsSynchronizationActive())
            {
                TransactionSynchronizationManager.RegisterSynchronization(new RabbitResourceSynchronization(resourceHolder, connectionFactory));
            }

            return(resourceHolder);
        }
Пример #6
0
        /// <summary>
        /// Method DoGetConnection does the actual Connection creation/recuperation
        /// It throws the orgiginal DB4o Exceptions
        /// </summary>
        /// <param name="dataSource">An IDb4oDataSource</param>
        /// <returns>An ObjectContainer</retutns>
        private static ObjectContainer DoGetConnection(IDb4oDataSource dataSource)
        {
            logger.Debug("Do Get Connection");
            logger.Debug("GetResource from TransactionSynchronizationManager");
            ObjectContainerHolder holder = (ObjectContainerHolder )TransactionSynchronizationManager.GetResource(dataSource);

            ObjectContainer container;

            if (holder != null)
            {
                logger.Debug("ObjectContainerHolder exists");
                holder.Requested();
                if (holder.ObjectContainer == null)
                {
                    logger.Debug("No connection inside the ObjectContainerHolder");
                    logger.Debug("Creating One");
                    holder.ObjectContainer = dataSource.GetConnection();
                }
                container = holder.ObjectContainer;
            }
            else
            {
                // the connection should be created
                logger.Debug("The Holder does not exist. It will be created");
                container = dataSource.GetConnection();
                if (TransactionSynchronizationManager.SynchronizationActive)
                {
                    logger.Debug("Registerbe increaseing transaction synchronization");
                    logger.Debug("Will use the same connection for further DB4o actions within the transaction");
                    logger.Debug("Thread-bound object will get removed by synchronization at transaction completion");
                    holder = new ObjectContainerHolder(container);
                    holder.SynchronizedWithTransaction = true;
                    holder.Requested();
                    TransactionSynchronizationManager.RegisterSynchronization(
                        new ObjectContainerSynchronization(holder, dataSource));
                    TransactionSynchronizationManager.BindResource(dataSource, holder);
                }
            }

            return(container);
        }
Пример #7
0
        private static ISession DoGetSession(
            ISessionFactory sessionFactory, IInterceptor entityInterceptor,
            IAdoExceptionTranslator adoExceptionTranslator, bool allowCreate)
        {
            AssertUtils.ArgumentNotNull(sessionFactory, "sessionFactory", "SessionFactory can not be null");

            SessionHolder sessionHolder = (SessionHolder)TransactionSynchronizationManager.GetResource(sessionFactory);

            if (sessionHolder != null && !sessionHolder.IsEmpty)
            {
                // pre-bound Hibernate Session
                ISession session = null;
                if (TransactionSynchronizationManager.SynchronizationActive &&
                    sessionHolder.DoesNotHoldNonDefaultSession)
                {
                    // Spring transaction management is active ->
                    // register pre-bound Session with it for transactional flushing.
                    session = sessionHolder.ValidatedSession;
                    if (!sessionHolder.SynchronizedWithTransaction)
                    {
                        log.Debug("Registering Spring transaction synchronization for existing Hibernate Session");
                        TransactionSynchronizationManager.RegisterSynchronization(
                            new SpringSessionSynchronization(sessionHolder, sessionFactory, adoExceptionTranslator, false));
                        sessionHolder.SynchronizedWithTransaction = true;
                        // Switch to FlushMode.AUTO if we're not within a read-only transaction.
                        FlushMode flushMode = session.FlushMode;
                        if (FlushMode.Never == flushMode &&
                            !TransactionSynchronizationManager.CurrentTransactionReadOnly)
                        {
                            session.FlushMode = FlushMode.Auto;
                            sessionHolder.PreviousFlushMode = flushMode;
                        }
                    }
                }
                else
                {
                    // No Spring transaction management active -> simply return default thread-bound Session, if any
                    // (possibly from OpenSessionInViewModule)
                    session = sessionHolder.ValidatedSession;
                }

                if (session != null)
                {
                    return(session);
                }
            }


            ISession sess = OpenSession(sessionFactory, entityInterceptor);

            // Set Session to FlushMode.Never if we're within a read-only transaction.
            // Use same Session for further Hibernate actions within the transaction.
            // Thread object will get removed by synchronization at transaction completion.
            if (TransactionSynchronizationManager.SynchronizationActive)
            {
                log.Debug("Registering Spring transaction synchronization for new Hibernate Session");
                SessionHolder holderToUse = sessionHolder;
                if (holderToUse == null)
                {
                    holderToUse = new SessionHolder(sess);
                }
                else
                {
                    holderToUse.AddSession(sess);
                }
                if (TransactionSynchronizationManager.CurrentTransactionReadOnly)
                {
                    sess.FlushMode = FlushMode.Never;
                }
                TransactionSynchronizationManager.RegisterSynchronization(
                    new SpringSessionSynchronization(holderToUse, sessionFactory, adoExceptionTranslator, true));
                holderToUse.SynchronizedWithTransaction = true;
                if (holderToUse != sessionHolder)
                {
                    TransactionSynchronizationManager.BindResource(sessionFactory, holderToUse);
                }
            }



            // Check whether we are allowed to return the Session.
            if (!allowCreate && !IsSessionTransactional(sess, sessionFactory))
            {
                CloseSession(sess);
                throw new InvalidOperationException("No Hibernate Session bound to thread, " +
                                                    "and configuration does not allow creation of non-transactional one here");
            }

            return(sess);
        }
        private static MongoDatabase DoGetDatabase(MongoServer mongo, string databaseName, MongoCredentials credentials,
                                                   WriteConcern writeConcern, bool allowCreate)
        {
            var dbHolder = (DatabaseHolder)TransactionSynchronizationManager.GetResource(mongo);

            // Do we have a populated holder and TX sync active?
            if (dbHolder != null && !dbHolder.IsEmpty && TransactionSynchronizationManager.SynchronizationActive)
            {
                var holderDatabase = dbHolder.GetDatabase(databaseName);

                // DB found but not yet synchronized
                if (holderDatabase != null && !dbHolder.SynchronizedWithTransaction)
                {
                    Log.Debug(
                        m => m("Registering Spring transaction synchronization for existing MongoDB {0}.", databaseName));

                    TransactionSynchronizationManager.RegisterSynchronization(new MongoSynchronization(dbHolder, mongo));
                    dbHolder.SynchronizedWithTransaction = true;
                }

                if (holderDatabase != null)
                {
                    return(holderDatabase);
                }
            }

            // Lookup fresh database instance
            Log.Debug(m => m("Getting Mongo Database name=[{0}]", databaseName));

            if (writeConcern == null)
            {
                writeConcern = WriteConcern.Acknowledged;
            }

            var newDatabase = credentials != null
                                  ? mongo.GetDatabase(databaseName, credentials, writeConcern)
                                  : mongo.GetDatabase(databaseName, writeConcern);

            // TX sync active, bind new database to thread
            if (TransactionSynchronizationManager.SynchronizationActive)
            {
                Log.Debug(
                    m => m("Registering Spring transaction synchronization for MongoDB instance {0}.", databaseName));

                DatabaseHolder holderToUse = dbHolder;

                if (holderToUse == null)
                {
                    holderToUse = new DatabaseHolder(databaseName, newDatabase);
                }
                else
                {
                    holderToUse.AddDatabase(databaseName, newDatabase);
                }

                TransactionSynchronizationManager.RegisterSynchronization(new MongoSynchronization(holderToUse, mongo));
                holderToUse.SynchronizedWithTransaction = true;

                if (holderToUse != dbHolder)
                {
                    TransactionSynchronizationManager.BindResource(mongo, holderToUse);
                }
            }

            // Check whether we are allowed to return the DB.
            if (!allowCreate && !IsDbTransactional(newDatabase, mongo))
            {
                throw new InvalidOperationException("No Mongo DB bound to thread, "
                                                    +
                                                    "and configuration does not allow creation of non-transactional one here");
            }

            return(newDatabase);
        }
Пример #9
0
        /// <summary>
        /// Obtain a EMS Session that is synchronized with the current transaction, if any.
        /// </summary>
        /// <param name="resourceKey">the TransactionSynchronizationManager key to bind to
        /// (usually the ConnectionFactory)</param>
        /// <param name="resourceFactory">the ResourceFactory to use for extracting or creating
        /// EMS resources</param>
        /// <param name="startConnection">whether the underlying Connection approach should be
        /// started in order to allow for receiving messages. Note that a reused Connection
        /// may already have been started before, even if this flag is <code>false</code>.</param>
        /// <returns>
        /// the transactional Session, or <code>null</code> if none found
        /// </returns>
        /// <throws>EMSException in case of EMS failure </throws>
        public static ISession DoGetTransactionalSession(Object resourceKey, ResourceFactory resourceFactory, bool startConnection)
        {
            AssertUtils.ArgumentNotNull(resourceKey, "Resource key must not be null");
            AssertUtils.ArgumentNotNull(resourceKey, "ResourceFactory must not be null");

            EmsResourceHolder resourceHolder =
                (EmsResourceHolder)TransactionSynchronizationManager.GetResource(resourceKey);

            if (resourceHolder != null)
            {
                ISession rhSession = resourceFactory.GetSession(resourceHolder);
                if (rhSession != null)
                {
                    if (startConnection)
                    {
                        IConnection conn = resourceFactory.GetConnection(resourceHolder);
                        if (conn != null)
                        {
                            conn.Start();
                        }
                    }
                    return(rhSession);
                }
            }
            if (!TransactionSynchronizationManager.SynchronizationActive)
            {
                return(null);
            }
            EmsResourceHolder resourceHolderToUse = resourceHolder;

            if (resourceHolderToUse == null)
            {
                resourceHolderToUse = new EmsResourceHolder();
            }

            IConnection con     = resourceFactory.GetConnection(resourceHolderToUse);
            ISession    session = null;

            try
            {
                bool isExistingCon = (con != null);
                if (!isExistingCon)
                {
                    con = resourceFactory.CreateConnection();
                    resourceHolderToUse.AddConnection(con);
                }
                session = resourceFactory.CreateSession(con);
                resourceHolderToUse.AddSession(session, con);
                if (startConnection)
                {
                    con.Start();
                }
            }
            catch (EMSException)
            {
                if (session != null)
                {
                    try
                    {
                        session.Close();
                    }
                    catch (Exception)
                    {
                        // ignore
                    }
                }
                if (con != null)
                {
                    try
                    {
                        con.Close();
                    }
                    catch (Exception)
                    {
                        // ignore
                    }
                }
                throw;
            }
            if (resourceHolderToUse != resourceHolder)
            {
                TransactionSynchronizationManager.RegisterSynchronization(
                    new EmsResourceSynchronization(resourceHolderToUse,
                                                   resourceKey, resourceFactory.SynchedLocalTransactionAllowed));
                resourceHolderToUse.SynchronizedWithTransaction = true;
                TransactionSynchronizationManager.BindResource(resourceKey, resourceHolderToUse);
            }
            return(session);
        }