/// <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> /// Applies the specified timeout - overridden by the current transaction timeout, if any, to to the /// given ADO.NET IDb command object. /// </summary> /// <param name="command">The command.</param> /// <param name="dbProvider">The db provider the command was obtained from.</param> /// <param name="timeout">The timeout to apply (or 0 for no timeout outside of a transaction.</param> public static void ApplyTransactionTimeout(IDbCommand command, IDbProvider dbProvider, int timeout) { AssertUtils.ArgumentNotNull(command, "command", "No IDbCommand specified."); AssertUtils.ArgumentNotNull(dbProvider, "dbProvider", "No IDbProvider specified."); ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.GetResource(dbProvider); if (conHolder != null && conHolder.HasTimeout) { // Remaining transaction timeout overrides specified value. command.CommandTimeout = conHolder.TimeToLiveInSeconds; } else if (timeout != -1) { // No current transaction timeout -> apply specified value. 0 = infinite timeout in some drivers. command.CommandTimeout = timeout; } }
private static void DoDisposeConnection(IDbConnection conn, IDbProvider dbProvider) { if (conn == null) { return; } if (dbProvider != null) { ConnectionHolder conHolder = (ConnectionHolder)TransactionSynchronizationManager.GetResource(dbProvider); if (conHolder != null && ConnectionEquals(conHolder.Connection, conn)) { // It's the transactional connection bound to the thread so don't close it. conHolder.Released(); return; } } if (LOG.IsDebugEnabled) { LOG.Debug("Disposing of IDbConnection with connection string = [" + dbProvider.ConnectionString + "]"); } conn.Dispose(); }
public SuspendedResourcesHolder(SessionHolder sessionHolder, ConnectionHolder conHolder) { this.sessionHolder = sessionHolder; this.connectionHolder = conHolder; }
/// <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) { 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) //if (txObject.SessionHolder == null || (txObject.SessionHolder.SynchronizedWithTransaction && TransactionSynchronizationManager.SynchronizationActive)) //if (txObject.SessionHolder == null || (txObject.SessionHolder.SynchronizedWithTransaction && TransactionSynchronizationManager.ActualTransactionActive)) { 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); } }
/// <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); }
public void SetConnectionHolder(ConnectionHolder connectionHolder, bool newConnection) { ConnectionHolder = connectionHolder; newConnectionHolder = newConnection; }
/// <summary> /// Create a new instance. /// </summary> /// <param name="connHolder"></param> /// <param name="provider"></param> public ConnectionSynchronization(ConnectionHolder connHolder, IDbProvider provider) { connectionHolder = connHolder; dbProvider = provider; order = ConnectionUtils.CONNECTION_SYNCHRONIZATION_ORDER; }
/// <summary> /// Create a new instance. /// </summary> /// <param name="connHolder"></param> /// <param name="provider"></param> public ConnectionSynchronization(ConnectionHolder connHolder, IDbProvider provider) { connectionHolder = connHolder; dbProvider = provider; order = ConnectionUtils.CONNECTION_SYNCHRONIZATION_ORDER; }