Beispiel #1
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));
        }
Beispiel #2
0
        /// <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;
            }
        }
Beispiel #3
0
        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;
		}
Beispiel #9
0
 /// <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;
 }