Exemple #1
0
        //// NOTE: This is just a private helper because OracleClient V1.1 shipped
        //// with a different argument name and it's a breaking change to not use
        //// the same argument names in V2.0 (VB Named Parameter Binding--Ick)
        //private void EnlistDistributedTransactionHelper(System.EnterpriseServices.ITransaction transaction) {
        //    SysTx.Transaction indigoTransaction = null;

        //    if (null != transaction) {
        //        indigoTransaction = SysTx.TransactionInterop.GetTransactionFromDtcTransaction((SysTx.IDtcTransaction)transaction);
        //    }

        //    RepairInnerConnection();
        //    // NOTE: since transaction enlistment involves round trips to the
        //    // server, we don't want to lock here, we'll handle the race conditions
        //    // elsewhere.
        //    InnerConnection.EnlistTransaction(indigoTransaction);

        //    // NOTE: If this outer connection were to be GC'd while we're
        //    // enlisting, the pooler would attempt to reclaim the inner connection
        //    // while we're attempting to enlist; not sure how likely that is but
        //    // we should consider a GC.KeepAlive(this) here.
        //    GC.KeepAlive(this);
        //}

        public override void EnlistTransaction(SysTx.Transaction?transaction)
        {
            // If we're currently enlisted in a transaction and we were called
            // on the EnlistTransaction method (Whidbey) we're not allowed to
            // enlist in a different transaction.

            DbConnectionInternal innerConnection = InnerConnection;

            // NOTE: since transaction enlistment involves round trips to the
            // server, we don't want to lock here, we'll handle the race conditions
            // elsewhere.
            SysTx.Transaction?enlistedTransaction = innerConnection.EnlistedTransaction;
            if (enlistedTransaction != null)
            {
                // Allow calling enlist if already enlisted (no-op)
                if (enlistedTransaction.Equals(transaction))
                {
                    return;
                }

                // Allow enlisting in a different transaction if the enlisted transaction has completed.
                if (enlistedTransaction.TransactionInformation.Status == SysTx.TransactionStatus.Active)
                {
                    throw ADP.TransactionPresent();
                }
            }
            RepairInnerConnection();
            InnerConnection.EnlistTransaction(transaction);

            // NOTE: If this outer connection were to be GC'd while we're
            // enlisting, the pooler would attempt to reclaim the inner connection
            // while we're attempting to enlist; not sure how likely that is but
            // we should consider a GC.KeepAlive(this) here.
            GC.KeepAlive(this);
        }
Exemple #2
0
 public override void EnlistTransaction(SysTx.Transaction?transaction)
 {
     if (null != LocalTransaction)
     {
         throw ADP.LocalTransactionPresent();
     }
     EnlistTransactionInternal(transaction);
 }
        internal void ActivateConnection(SysTx.Transaction?transaction)
        {
            // Internal method called from the connection pooler so we don't expose
            // the Activate method publicly.
#if DEBUG
            int activateCount = Interlocked.Increment(ref _activateCount);
            Debug.Assert(1 == activateCount, "activated multiple times?");
#endif // DEBUG

            Activate(transaction);

            PerformanceCounters !.NumberOfActiveConnections.Increment();
        }
Exemple #4
0
        internal void EnlistTransactionInternal(SysTx.Transaction?transaction)
        {
            SysTx.IDtcTransaction?oleTxTransaction = ADP.GetOletxTransaction(transaction);

            using (ITransactionJoinWrapper transactionJoin = ITransactionJoin())
            {
                if (null == transactionJoin.Value)
                {
                    throw ODB.TransactionsNotSupported(Provider, null);
                }
                transactionJoin.Value.JoinTransaction(oleTxTransaction, (int)IsolationLevel.Unspecified, 0, IntPtr.Zero);
                _unEnlistDuringDeactivate = (null != transaction);
            }
            EnlistedTransaction = transaction;
        }
Exemple #5
0
        public virtual void Dispose()
        {
            _connectionPool              = null;
            _performanceCounters         = null;
            _connectionIsDoomed          = true;
            _enlistedTransactionOriginal = null; // should not be disposed

            // Dispose of the _enlistedTransaction since it is a clone
            // of the original reference.
            // _enlistedTransaction can be changed by another thread (TX end event)
            SysTx.Transaction?enlistedTransaction = Interlocked.Exchange(ref _enlistedTransaction, null);
            if (enlistedTransaction != null)
            {
                enlistedTransaction.Dispose();
            }
        }
 internal void DetachCurrentTransactionIfEnded()
 {
     SysTx.Transaction?enlistedTransaction = EnlistedTransaction;
     if (enlistedTransaction != null)
     {
         bool transactionIsDead;
         try
         {
             transactionIsDead = (SysTx.TransactionStatus.Active != enlistedTransaction.TransactionInformation.Status);
         }
         catch (SysTx.TransactionException)
         {
             // If the transaction is being processed (i.e. is part way through a rollback\commit\etc then TransactionInformation.Status will throw an exception)
             transactionIsDead = true;
         }
         if (transactionIsDead)
         {
             DetachTransaction(enlistedTransaction, true);
         }
     }
 }
        // Detach transaction from connection.
        internal void DetachTransaction(SysTx.Transaction transaction, bool isExplicitlyReleasing)
        {
            // potentially a multi-threaded event, so lock the connection to make sure we don't enlist in a new
            // transaction between compare and assignment. No need to short circuit outside of lock, since failed comparisons should
            // be the exception, not the rule.
            lock (this)
            {
                // Detach if detach-on-end behavior, or if outer connection was closed
                DbConnection?owner = (DbConnection?)Owner;
                if (isExplicitlyReleasing || UnbindOnTransactionCompletion || null == owner)
                {
                    SysTx.Transaction?currentEnlistedTransaction = _enlistedTransaction;
                    if (currentEnlistedTransaction != null && transaction.Equals(currentEnlistedTransaction))
                    {
                        EnlistedTransaction = null;

                        if (IsTxRootWaitingForTxEnd)
                        {
                            DelegatedTransactionEnded();
                        }
                    }
                }
            }
        }
Exemple #8
0
 protected override void Activate(SysTx.Transaction?transaction)
 {
     throw ADP.NotSupported();
 }
 public abstract void EnlistTransaction(SysTx.Transaction?transaction);
 protected abstract void Activate(SysTx.Transaction?transaction);
 public override void EnlistTransaction(SysTx.Transaction?transaction)
 {
     throw ADP.ClosedConnectionError();
 }
 protected override void Activate(SysTx.Transaction?transaction)
 {
     throw ADP.ClosedConnectionError();
 }