示例#1
0
 public IDbConnection Disconnect()
 {
     if (IsInActiveTransaction)
     {
         throw new InvalidOperationException("Disconnect cannot be called while a transaction is in progress.");
     }
     try
     {
         if (!ownConnection)
         {
             return(DisconnectSuppliedConnection());
         }
         else
         {
             DisconnectOwnConnection();
             ownConnection = false;
             return(null);
         }
     }
     finally
     {
         // Ensure that AfterTransactionCompletion gets called since
         // it takes care of the locks and cache.
         if (!IsInActiveTransaction)
         {
             // We don't know the state of the transaction
             session.AfterTransactionCompletion(false, null);
         }
     }
 }
示例#2
0
 void IEnlistmentNotification.Rollback(Enlistment enlistment)
 {
     using (new SessionIdLoggingContext(sessionImplementor.SessionId))
     {
         sessionImplementor.AfterTransactionCompletion(false, null);
         logger.Debug("rolled back DTC transaction");
         enlistment.Done();
         IsInActiveTransaction = false;
     }
 }
示例#3
0
            void IEnlistmentNotification.InDoubt(Enlistment enlistment)
            {
                using (new SessionIdLoggingContext(session.SessionId))
                {
                    session.AfterTransactionCompletion(false, null);
                    logger.Debug("DTC transaction is in doubt");

                    End(false);

                    enlistment.Done();
                    IsInActiveTransaction = false;
                }
            }
示例#4
0
        /// <summary>
        /// Invoked after transaction commit/rollback.
        /// </summary>
        /// <param name="status">
        /// Status according to <see cref="Spring.Transaction.Support.TransactionSynchronizationStatus"/>
        /// </param>
        /// <remarks>
        /// Can e.g. perform resource cleanup, in this case after transaction completion.
        /// <p>
        /// Note that exceptions will get propagated to the commit or rollback
        /// caller, although they will not influence the outcome of the transaction.
        /// </p>
        /// </remarks>
        public override void AfterCompletion(TransactionSynchronizationStatus status)
        {
            if (!newSession)
            {
                ISession session = sessionHolder.Session;

                // Provide correct transaction status for releasing the Session's cache locks,
                // if possible. Else, closing will release all cache locks assuming a rollback.
                ISessionImplementor sessionImplementor = session as ISessionImplementor;
                if (sessionImplementor != null)
                {
                    sessionImplementor.AfterTransactionCompletion(status == TransactionSynchronizationStatus.Committed, sessionHolder.Transaction);
                }

                if (newSession)
                {
                    SessionFactoryUtils.CloseSessionOrRegisterDeferredClose(session, sessionFactory);
                }
            }
            if (!newSession && status != TransactionSynchronizationStatus.Committed)
            {
                // Clear all pending inserts/updates/deletes in the Session.
                // Necessary for pre-bound Sessions, to avoid inconsistent state.
                sessionHolder.Session.Clear();
            }

            if (this.sessionHolder.DoesNotHoldNonDefaultSession)
            {
                sessionHolder.SynchronizedWithTransaction = false;
            }
        }
		public void EnlistInDistributedTransactionIfNeeded(ISessionImplementor session)
		{
			if (session.TransactionContext != null)
				return;
			if (System.Transactions.Transaction.Current == null)
				return;
			var transactionContext = new DistributedTransactionContext(session, System.Transactions.Transaction.Current);
			session.TransactionContext = transactionContext;
			logger.DebugFormat("enlisted into DTC transaction: {0}", transactionContext.AmbientTransation.IsolationLevel);
			session.AfterTransactionBegin(null);
			transactionContext.AmbientTransation.TransactionCompleted += delegate(object sender, TransactionEventArgs e)
			{
				bool wasSuccessful = false;
				try
				{
					wasSuccessful = e.Transaction.TransactionInformation.Status
					                == TransactionStatus.Committed;
				}
				catch (ObjectDisposedException ode)
				{
					logger.Warn("Completed transaction was disposed, assuming transaction rollback", ode);
				}
				session.AfterTransactionCompletion(wasSuccessful, null);
				if (transactionContext.ShouldCloseSessionOnDistributedTransactionCompleted)
				{
					session.CloseSessionFromDistributedTransaction();
				}
				session.TransactionContext = null;
			};
			transactionContext.AmbientTransation.EnlistVolatile(transactionContext, EnlistmentOptions.EnlistDuringPrepareRequired);
		}
        public void EnlistInDistributedTransactionIfNeeded(ISessionImplementor session)
        {
            if (session.TransactionContext != null)
            {
                return;
            }

            if (System.Transactions.Transaction.Current == null)
            {
                return;
            }

            var transactionContext = new DistributedTransactionContext(session, System.Transactions.Transaction.Current);

            session.TransactionContext = transactionContext;
            logger.DebugFormat("enlisted into DTC transaction: {0}",
                               transactionContext.AmbientTransation.IsolationLevel);
            session.AfterTransactionBegin(null);

            //use pull-request https://github.com/nhibernate/nhibernate-core/pull/206 (with handler manipulation)

            TransactionCompletedEventHandler handler = null;

            handler =
                delegate(object sender, TransactionEventArgs e)
            {
                lock (session)
                {
                    using (new SessionIdLoggingContext(session.SessionId))
                    {
                        ((DistributedTransactionContext)session.TransactionContext).IsInActiveTransaction = false;

                        bool wasSuccessful = false;
                        try
                        {
                            wasSuccessful = e.Transaction.TransactionInformation.Status
                                            == TransactionStatus.Committed;
                        }
                        catch (ObjectDisposedException ode)
                        {
                            logger.Warn("Completed transaction was disposed, assuming transaction rollback", ode);
                        }
                        session.AfterTransactionCompletion(wasSuccessful, null);

                        if (transactionContext.ShouldCloseSessionOnDistributedTransactionCompleted)
                        {
                            session.CloseSessionFromDistributedTransaction();
                        }
                        session.TransactionContext = null;
                    }

                    transactionContext.AmbientTransation.TransactionCompleted -= handler;
                }
            };

            transactionContext.AmbientTransation.TransactionCompleted += handler;

            transactionContext.AmbientTransation.EnlistVolatile(transactionContext,
                                                                EnlistmentOptions.EnlistDuringPrepareRequired);
        }
示例#7
0
            /// <summary>
            /// Handle the transaction completion. Notify <see cref="ConnectionManager"/> of the end of the
            /// transaction. Notify end of transaction to the session and to <see cref="ConnectionManager.DependentSessions"/>
            /// if any. Close sessions requiring it then cleanup transaction contextes and then <see cref="Unlock"/> blocked
            /// threads.
            /// </summary>
            /// <param name="isCommitted"><see langword="true"/> if the transaction is committed, <see langword="false"/>
            /// otherwise.</param>
            protected virtual void CompleteTransaction(bool isCommitted)
            {
                // Some implementations (Mono) may "re-complete" the transaction on the cloned transaction disposal:
                // do an early exit here in such case.
                if (!IsInActiveTransaction)
                {
                    return;
                }
                try
                {
                    // Allow transaction completed actions to run while others stay blocked.
                    _bypassLock.Value = true;
                    using (_session.BeginContext())
                    {
                        // Flag active as false before running actions, otherwise the session may not cleanup as much
                        // as possible.
                        IsInActiveTransaction = false;
                        // Never allows using connection on after transaction event. And tell the connection manager
                        // it is called from system transaction. Allows releasing of connection on next usage
                        // when release mode is on commit, allows un-enlisting the connection on next usage
                        // when release mode is on close. Without BeginsProcessingFromSystemTransaction(false),
                        // the connection manager would attempt those operations immediately, causing concurrency
                        // issues and crashes for some data providers.
                        using (_session.ConnectionManager.BeginProcessingFromSystemTransaction(false))
                        {
                            _session.ConnectionManager.AfterTransaction();
                            // Required for un-enlisting the connection manager when auto-join is false.
                            // Not done in AfterTransaction, because users may use NHibernate transactions
                            // within scopes, although mixing is not advised.
                            if (!ShouldCloseSessionOnSystemTransactionCompleted)
                            {
                                _session.ConnectionManager.EnlistIfRequired(null);
                            }

                            _session.AfterTransactionCompletion(isCommitted, null);
                            foreach (var dependentSession in _session.ConnectionManager.DependentSessions)
                            {
                                dependentSession.AfterTransactionCompletion(isCommitted, null);
                            }

                            Cleanup(_session);
                        }
                    }
                }
                catch (Exception ex)
                {
                    // May be run in a dedicated thread. Log any error, otherwise they could stay unlogged.
                    _logger.Error(ex, "Failure at transaction completion");
                    throw;
                }
                finally
                {
                    // Dispose releases blocked threads by the way.
                    Dispose();
                }
            }
示例#8
0
 private void AfterTransactionCompletion(bool successful)
 {
     using (new SessionIdLoggingContext(sessionId))
     {
         session.AfterTransactionCompletion(successful, this);
         NotifyLocalSynchsAfterTransactionCompletion(successful);
         session = null;
         begun   = false;
     }
 }
示例#9
0
        private void AfterTransactionCompletion(bool successful)
        {
            session.ConnectionManager.AfterTransaction();
            session.AfterTransactionCompletion(successful, this);
            NotifyLocalSynchsAfterTransactionCompletion(successful);
            foreach (var dependentSession in session.ConnectionManager.DependentSessions)
            {
                dependentSession.AfterTransactionCompletion(successful, this);
            }

            session = null;
            begun   = false;
        }
 void IEnlistmentNotification.InDoubt(Enlistment enlistment)
 {
     using (new SessionIdLoggingContext(sessionImplementor.SessionId))
     {
         sessionImplementor.ConnectionManager.AfterTransaction();
         sessionImplementor.AfterTransactionCompletion(false, null);
         foreach (var dependentSession in sessionImplementor.ConnectionManager.DependentSessions)
         {
             dependentSession.AfterTransactionCompletion(false, null);
         }
         logger.Debug("DTC transaction is in doubt");
         enlistment.Done();
         IsInActiveTransaction = false;
     }
 }
        public void EnlistInDistributedTransactionIfNeeded(ISessionImplementor session)
        {
            if (session.TransactionContext != null)
            {
                return;
            }

            if (System.Transactions.Transaction.Current == null)
            {
                return;
            }

            var transactionContext = new DistributedTransactionContext(session,
                                                                       System.Transactions.Transaction.Current);

            session.TransactionContext = transactionContext;
            logger.DebugFormat("enlisted into DTC transaction: {0}",
                               transactionContext.AmbientTransation.IsolationLevel);
            session.AfterTransactionBegin(null);
            transactionContext.AmbientTransation.TransactionCompleted +=
                delegate(object sender, TransactionEventArgs e)
            {
                using (new SessionIdLoggingContext(session.SessionId))
                {
                    bool wasSuccessful = false;
                    try
                    {
                        wasSuccessful = e.Transaction.TransactionInformation.Status
                                        == TransactionStatus.Committed;
                    }
                    catch (ObjectDisposedException ode)
                    {
                        logger.Warn("Completed transaction was disposed, assuming transaction rollback", ode);
                    }
                    session.AfterTransactionCompletion(wasSuccessful, null);
                    if (transactionContext.ShouldCloseSessionOnDistributedTransactionCompleted)
                    {
                        session.CloseSessionFromDistributedTransaction();
                    }
                    session.TransactionContext = null;
                }
            };
            transactionContext.AmbientTransation.EnlistVolatile(transactionContext,
                                                                EnlistmentOptions.EnlistDuringPrepareRequired);
        }
        public void EnlistInDistributedTransactionIfNeeded(ISessionImplementor session)
        {
            if (session.TransactionContext != null)
            {
                return;
            }

            if (System.Transactions.Transaction.Current == null)
            {
                return;
            }

            var originatingSession = session.ConnectionManager.Session;

            if (originatingSession != session)
            {
                session.TransactionContext = new DependentContext();
            }

            if (originatingSession.TransactionContext != null)
            {
                return;
            }

            session = originatingSession;

            var transactionContext = new DistributedTransactionContext(session,
                                                                       System.Transactions.Transaction.Current);

            session.TransactionContext = transactionContext;
            logger.DebugFormat("enlisted into DTC transaction: {0}",
                               transactionContext.AmbientTransation.IsolationLevel);
            session.AfterTransactionBegin(null);
            foreach (var dependentSession in session.ConnectionManager.DependentSessions)
            {
                dependentSession.AfterTransactionBegin(null);
            }

            TransactionCompletedEventHandler handler = null;

            handler = delegate(object sender, TransactionEventArgs e)
            {
                using (new SessionIdLoggingContext(session.SessionId))
                {
                    ((DistributedTransactionContext)session.TransactionContext).IsInActiveTransaction = false;

                    bool wasSuccessful = false;
                    try
                    {
                        wasSuccessful = e.Transaction.TransactionInformation.Status
                                        == TransactionStatus.Committed;
                    }
                    catch (ObjectDisposedException ode)
                    {
                        logger.Warn("Completed transaction was disposed, assuming transaction rollback", ode);
                    }
                    session.ConnectionManager.AfterTransaction();
                    session.AfterTransactionCompletion(wasSuccessful, null);
                    foreach (var dependentSession in session.ConnectionManager.DependentSessions)
                    {
                        dependentSession.AfterTransactionCompletion(wasSuccessful, null);
                    }

                    Cleanup(session);
                }

                e.Transaction.TransactionCompleted -= handler;
            };

            transactionContext.AmbientTransation.TransactionCompleted += handler;

            transactionContext.AmbientTransation.EnlistVolatile(transactionContext,
                                                                EnlistmentOptions.EnlistDuringPrepareRequired);
        }
示例#13
0
 private void AfterTransactionCompletion(bool successful)
 {
     session.AfterTransactionCompletion(successful, this);
     session = null;
     begun   = false;
 }
示例#14
0
 public void AfterTransactionCompletion(bool successful, ITransaction tx)
 {
     _session.AfterTransactionCompletion(successful, tx);
 }
示例#15
0
 private void AfterTransactionCompletion(bool successful)
 {
     session.AfterTransactionCompletion(successful);
     session = null;
 }
 public void afterTransactionCompletion(bool successful, ITransaction tx)
 {
     delegat.AfterTransactionCompletion(successful, tx);
 }