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(); }
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(); }
/// <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)); } }
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); }
/// <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); }
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); }
/// <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); }