protected override void DoBegin(object transaction, ITransactionDefinition definition)
 {
     if (this.sqlMapper == null)
     {
         throw new ArgumentException("SqlMapper is required to be set on IbatisPlatformTransactionManager");
     }
     this.sqlMapper.BeginTransaction(); ;
 }
 /// <summary>
 /// Determines the timeout to use for the given definition.  Will fall back to this manager's default
 /// timeout if the transaction definition doesn't specify a non-default value.
 /// </summary>
 /// <param name="definition">The transaction definition.</param>
 /// <returns>the actual timeout to use.</returns>
 protected int DetermineTimeout(ITransactionDefinition definition)
 {
     if (definition.TransactionTimeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT)
     {
         return definition.TransactionTimeout;
     }
     return _defaultTimeout;
 }
        private ITransactionStatus HandleExistingTransaction(ITransactionDefinition definition, object transaction, bool debugEnabled)
        {
            //bool newSynchronization;
            if (definition.PropagationBehavior == TransactionPropagation.Never)
            {
                throw new IllegalTransactionStateException(
                    "Transaction propagation 'never' but existing transaction found.");
            }
            if (definition.PropagationBehavior == TransactionPropagation.NotSupported)
            {
                if (debugEnabled)
                {
                    log.Debug("Suspending current transaction");
                }
                object suspendedResources = Suspend(transaction);
                bool newSynchronization = (_transactionSyncState == TransactionSynchronizationState.Always);
                return
                    PrepareTransactionStatus(definition, null, false, newSynchronization, debugEnabled,
                                         suspendedResources);
            }

            if (definition.PropagationBehavior == TransactionPropagation.RequiresNew)
            {
                if (debugEnabled)
                {
                    log.Debug("Suspending current transaction, creating new transaction with name [" +
                              definition.Name + "]:" + definition);
                }
                object suspendedResources = Suspend(transaction);
                try
                {
                    bool newSynchronization = (_transactionSyncState != TransactionSynchronizationState.Never);
                    DefaultTransactionStatus status = NewTransactionStatus(
                        definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
                    PrepareSynchronization(status, definition);
                    DoBegin(transaction, definition);
                    return status;
                }
                catch (TransactionException beginEx)
                {
                    try
                    {
                        Resume(transaction, suspendedResources);
                        //TODO: java code rethrows the ex here...should we do so as well?
                        //throw;
                    }
                    catch (TransactionException resumeEx)
                    {
                        log.Error(
                            "Inner transaction begin exception overridden by outer transaction resume exception");
                        log.Error("Begin Transaction Exception", beginEx);
                        log.Error("Resume Transaction Exception", resumeEx);
                        throw;
                    }
                    throw;
                }
            }
            if (definition.PropagationBehavior == TransactionPropagation.Nested)
            {
                if (!NestedTransactionsAllowed)
                {
                    throw new NestedTransactionNotSupportedException(
                        "Transaction manager does not allow nested transactions by default - " +
                        "specify 'NestedTransactionsAllowed' property with value 'true'");
                }
                if (debugEnabled)
                {
                    log.Debug("Creating nested transaction with name [" + definition.Name + "]:" + definition);
                }

                if (UseSavepointForNestedTransaction())
                {
                    DefaultTransactionStatus status =
                        PrepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
                    status.CreateAndHoldSavepoint(DateTime.Now.ToLongTimeString());
                    return status;
                }
                else
                {
                    bool newSynchronization = (_transactionSyncState != TransactionSynchronizationState.Never);
                    DefaultTransactionStatus status = NewTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);
                    PrepareSynchronization(status, definition);
                    DoBegin(transaction, definition);
                    return status;

                }
            }
            // Assumably PROPAGATION_SUPPORTS.
            if (debugEnabled)
            {
                log.Debug("Participating in existing transaction");
            }

            //TODO: this block related to un-ported java feature permitting setting the ValidateExistingTransaction flag 
            //  default is FALSE anyway so skipping this validation block should have no effect on code excecution path
            /*if (isValidateExistingTransaction())
            {
                if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT)
                {
                    Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
                    if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel())
                    {
                        Constants isoConstants = DefaultTransactionDefinition.constants;
                        throw new IllegalTransactionStateException("Participating transaction with definition [" +
                                definition + "] specifies isolation level which is incompatible with existing transaction: " +
                                (currentIsolationLevel != null ?
                                        isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
                                        "(unknown)"));
                    }
                }*/

                if (!definition.ReadOnly)
                {
                    if (TransactionSynchronizationManager.CurrentTransactionReadOnly)
                    {
                        throw new IllegalTransactionStateException("Participating transaction with definition [" +
                                definition + "] is not marked as read-only but existing transaction is");
                    }
                }
            
            bool newSynch = (_transactionSyncState != TransactionSynchronizationState.Never);
            return PrepareTransactionStatus(definition, transaction, false, newSynch, debugEnabled, null);

        }
 protected DefaultTransactionStatus PrepareTransactionStatus(
     ITransactionDefinition definition, Object transaction, bool newTransaction,
     bool newSynchronization, bool debug, Object suspendedResources)
 {
     DefaultTransactionStatus status = NewTransactionStatus(
             definition, transaction, newTransaction, newSynchronization, debug, suspendedResources);
     PrepareSynchronization(status, definition);
     return status;
 }
 /// <summary>
 /// Begin a new transaction with the given transaction definition.
 /// </summary>
 /// <remarks>
 /// Does not have to care about applying the propagation behavior,
 /// as this has already been handled by this abstract manager.
 /// </remarks>
 /// <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>
 /// <exception cref="Spring.Transaction.TransactionException">
 /// In the case of creation or system errors.
 /// </exception>
 protected abstract void DoBegin(object transaction, ITransactionDefinition definition);
        /**
         * Create a rae TransactionStatus instance for the given arguments.
         */

        /// <summary>The new transaction status.</summary>
        /// <param name="definition">The definition.</param>
        /// <param name="transaction">The transaction.</param>
        /// <param name="newTransaction">The new transaction.</param>
        /// <param name="newSynchronization">The new synchronization.</param>
        /// <param name="debug">The debug.</param>
        /// <param name="suspendedResources">The suspended resources.</param>
        /// <returns>The Spring.Transaction.Support.DefaultTransactionStatus.</returns>
        protected DefaultTransactionStatus NewTransactionStatus(ITransactionDefinition definition, object transaction, bool newTransaction, bool newSynchronization, bool debug, object suspendedResources)
        {
            var actualNewSynchronization = newSynchronization && !TransactionSynchronizationManager.SynchronizationActive;
            return new DefaultTransactionStatus(transaction, newTransaction, actualNewSynchronization, definition.ReadOnly, debug, suspendedResources);
        }
 protected virtual void PrepareSynchronization(DefaultTransactionStatus status, ITransactionDefinition definition)
 {
     if (status.IsNewSynchronization)
     {
         TransactionSynchronizationManager.SetActualTransactionActive(status.HasTransaction);
         TransactionSynchronizationManager.SetCurrentTransactionIsolationLevel(definition.IsolationLevel != AbstractTransactionDefinition.ISOLATION_DEFAULT ? definition.IsolationLevel : (int?)null);
         TransactionSynchronizationManager.SetCurrentTransactionReadOnly(definition.IsReadOnly);
         TransactionSynchronizationManager.SetCurrentTransactionName(definition.Name);
         TransactionSynchronizationManager.InitSynchronization();
     }
 }
        /// <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>
        /// <exception cref="Spring.Transaction.TransactionException">
        /// In the case of creation or system errors.
        /// </exception>
        protected override void DoBegin(object transaction, ITransactionDefinition definition)
        {
            MessageQueueTransactionObject txObject = (MessageQueueTransactionObject) transaction;

            MessageQueueTransaction mqt = new MessageQueueTransaction();
            mqt.Begin();

            txObject.ResourceHolder = new MessageQueueResourceHolder(mqt);
            txObject.ResourceHolder.SynchronizedWithTransaction = true;

            int timeout = DetermineTimeout(definition);
            if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT)
            {
                txObject.ResourceHolder.TimeoutInSeconds = timeout;
            }
            TransactionSynchronizationManager.BindResource(CURRENT_TRANSACTION_SLOTNAME, txObject.ResourceHolder);
        }
Esempio n. 9
0
        private void DoServiceDomainBegin(ServiceDomainTransactionObject serviceDomainTxObject, ITransactionDefinition definition)
        {
            SimpleServiceConfig serviceConfig = CreateServiceConfig(definition);

            //The context is created when we call Enter.
            serviceDomainTxObject.ServiceDomainAdapter.Enter(serviceConfig);
            if (log.IsDebugEnabled)
            {
                log.Debug("Context created. TransactionId = " + ContextUtil.TransactionId
                          + ", ActivityId = " + ContextUtil.ActivityId);
            }
        }
 protected override void DoBegin(object transaction, ITransactionDefinition definition)
 {
 }
Esempio n. 11
0
 /// <summary>The do begin.</summary>
 /// <param name="transaction">The transaction.</param>
 /// <param name="definition">The definition.</param>
 protected override void DoBegin(object transaction, ITransactionDefinition definition)
 {
     ((ResourcelessTransaction)transaction).Begin();
 }
Esempio n. 12
0
 public TransactionTemplate(IPlatformTransactionManager transactionManager, ITransactionDefinition transactionDefinition, ILogger logger = null)
     : base(transactionDefinition)
 {
     _logger            = logger;
     TransactionManager = transactionManager;
 }
        private ITransactionStatus HandleExistingTransaction(ITransactionDefinition definition, object transaction)
        {
            if (definition.PropagationBehavior == AbstractTransactionDefinition.PROPAGATION_NEVER)
            {
                throw new IllegalTransactionStateException(
                          "Existing transaction found for transaction marked with propagation 'never'");
            }

            if (definition.PropagationBehavior == AbstractTransactionDefinition.PROPAGATION_NOT_SUPPORTED)
            {
                _logger?.LogDebug("Suspending current transaction");
                var suspendedResources = Suspend(transaction);
                return(PrepareTransactionStatus(definition, null, false, TransactionSynchronization == SYNCHRONIZATION_ALWAYS, suspendedResources));
            }

            if (definition.PropagationBehavior == AbstractTransactionDefinition.PROPAGATION_REQUIRES_NEW)
            {
                _logger?.LogDebug("Suspending current transaction, creating new transaction with name [" + definition.Name + "]");
                var suspendedResources = Suspend(transaction);
                try
                {
                    var status = NewTransactionStatus(definition, transaction, true, TransactionSynchronization != SYNCHRONIZATION_NEVER, suspendedResources);
                    DoBegin(transaction, definition);
                    PrepareSynchronization(status, definition);
                    return(status);
                }
                catch (Exception ex)
                {
                    ResumeAfterBeginException(transaction, suspendedResources, ex);
                    throw;
                }
            }

            if (definition.PropagationBehavior == AbstractTransactionDefinition.PROPAGATION_NESTED)
            {
                if (!NestedTransactionAllowed)
                {
                    throw new NestedTransactionNotSupportedException(
                              "Transaction manager does not allow nested transactions by default - " +
                              "specify 'nestedTransactionAllowed' property with value 'true'");
                }

                _logger?.LogDebug("Creating nested transaction with name [" + definition.Name + "]");
                if (UseSavepointForNestedTransaction)
                {
                    // Create savepoint within existing Spring-managed transaction,
                    // through the SavepointManager API implemented by TransactionStatus.
                    // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
                    var status = PrepareTransactionStatus(definition, transaction, false, false, null);
                    status.CreateAndHoldSavepoint();
                    return(status);
                }
                else
                {
                    // Nested transaction through nested begin and commit/rollback calls.
                    // Usually only for JTA: Spring synchronization might get activated here
                    // in case of a pre-existing JTA transaction.
                    var status = NewTransactionStatus(definition, transaction, true, TransactionSynchronization != SYNCHRONIZATION_NEVER, null);
                    DoBegin(transaction, definition);
                    PrepareSynchronization(status, definition);
                    return(status);
                }
            }

            // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
            _logger?.LogDebug("Participating in existing transaction");
            if (ValidateExistingTransaction)
            {
                if (definition.IsolationLevel != AbstractTransactionDefinition.ISOLATION_DEFAULT)
                {
                    var currentIsolationLevel = TransactionSynchronizationManager.GetCurrentTransactionIsolationLevel();
                    if (currentIsolationLevel == null || currentIsolationLevel != definition.IsolationLevel)
                    {
                        throw new IllegalTransactionStateException("Participating transaction with definition [" +
                                                                   definition + "] specifies isolation level which is incompatible with existing transaction: ");
                    }
                }

                if (!definition.IsReadOnly && TransactionSynchronizationManager.IsCurrentTransactionReadOnly())
                {
                    throw new IllegalTransactionStateException("Participating transaction with definition [" +
                                                               definition + "] is not marked as read-only but existing transaction is");
                }
            }

            var newSynchronization = TransactionSynchronization != SYNCHRONIZATION_NEVER;

            return(PrepareTransactionStatus(definition, transaction, false, newSynchronization, null));
        }
 protected abstract void DoBegin(object transaction, ITransactionDefinition definition);
 /// <summary>
 /// Prevents the transaction.
 /// </summary>
 protected virtual void PreventTransaction()
 {
     this.transactionDefinition = null;
 }
        /// <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>
        /// 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.TimeoutInSeconds = timeout;
                    }
                    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);
            }
        }
        private static TransactionOptions CreateTransactionOptions(ITransactionDefinition definition)
        {
            TransactionOptions txOptions = new TransactionOptions();
            switch (definition.TransactionIsolationLevel )
            {
                case System.Data.IsolationLevel.Chaos:
                    txOptions.IsolationLevel = IsolationLevel.Chaos;
                    break;
                case System.Data.IsolationLevel.ReadCommitted:
                    txOptions.IsolationLevel = IsolationLevel.ReadCommitted;
                    break;
                case System.Data.IsolationLevel.ReadUncommitted:
                    txOptions.IsolationLevel = IsolationLevel.ReadUncommitted;
                    break;
                case System.Data.IsolationLevel.RepeatableRead:
                    txOptions.IsolationLevel = IsolationLevel.RepeatableRead;
                    break;
                case System.Data.IsolationLevel.Serializable:
                    txOptions.IsolationLevel = IsolationLevel.Serializable;
                    break;
                case System.Data.IsolationLevel.Snapshot:
                    txOptions.IsolationLevel = IsolationLevel.Snapshot;
                    break;
                case System.Data.IsolationLevel.Unspecified:
                    txOptions.IsolationLevel = IsolationLevel.Unspecified;
                    break;
            }

            if (definition.TransactionTimeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT)
            {                
                txOptions.Timeout = new TimeSpan(0, 0, definition.TransactionTimeout);
            }
            return txOptions;
        }
        protected virtual DefaultTransactionStatus NewTransactionStatus(ITransactionDefinition definition, object transaction, bool newTransaction, bool newSynchronization, object suspendedResources)
        {
            var actualNewSynchronization = newSynchronization && !TransactionSynchronizationManager.IsSynchronizationActive();

            return(new DefaultTransactionStatus(transaction, newTransaction, actualNewSynchronization, definition.IsReadOnly, suspendedResources, _logger));
        }
        /// <summary>Create a TransactionStatus for an existing transaction.</summary>
        /// <param name="definition">The transaction definition.</param>
        /// <param name="transaction">The transaction.</param>
        /// <param name="debugEnabled">Flag indicating debug is enabled.</param>
        /// <returns>The transaction status.</returns>
        private ITransactionStatus HandleExistingTransaction(ITransactionDefinition definition, object transaction, bool debugEnabled)
        {
            if (definition.PropagationBehavior == TransactionPropagation.Never)
            {
                throw new IllegalTransactionStateException(
                    "Existing transaction found for transaction marked with propagation 'never'");
            }

            if (definition.PropagationBehavior == TransactionPropagation.NotSupported)
            {
                if (debugEnabled)
                {
                    Logger.Debug("Suspending current transaction");
                }

                var suspendedResources = this.Suspend(transaction);
                var newSynchronization1 = this.transactionSynchronization == TransactionSynchronizationState.Always;
                return this.PrepareTransactionStatus(definition, null, false, newSynchronization1, debugEnabled, suspendedResources);
            }

            if (definition.PropagationBehavior == TransactionPropagation.RequiresNew)
            {
                if (debugEnabled)
                {
                    Logger.Debug(
                        "Suspending current transaction, creating new transaction with name [" +
                        definition.Name + "]");
                }

                var suspendedResources = this.Suspend(transaction);
                try
                {
                    var newSynchronization2 = this.transactionSynchronization != TransactionSynchronizationState.Never;
                    var status = this.NewTransactionStatus(definition, transaction, true, newSynchronization2, debugEnabled, suspendedResources);
                    this.DoBegin(transaction, definition);
                    this.PrepareSynchronization(status, definition);
                    return status;
                }
                catch (Exception beginEx)
                {
                    this.ResumeAfterBeginException(transaction, suspendedResources, beginEx);
                    throw;
                }
            }

            if (definition.PropagationBehavior == TransactionPropagation.Nested)
            {
                if (!this.nestedTransactionAllowed)
                {
                    throw new NestedTransactionNotSupportedException(
                        "Transaction manager does not allow nested transactions by default - " +
                        "specify 'nestedTransactionAllowed' property with value 'true'");
                }

                if (debugEnabled)
                {
                    Logger.Debug("Creating nested transaction with name [" + definition.Name + "]");
                }

                if (this.UseSavepointForNestedTransaction())
                {
                    // Create savepoint within existing Spring-managed transaction,
                    // through the SavepointManager API implemented by TransactionStatus.
                    // Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
                    var status = this.PrepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
                    status.CreateAndHoldSavepoint(Guid.NewGuid().ToString()); // TODO: Java equivalent does not require name
                    return status;
                }
                else
                {
                    // Nested transaction through nested begin and commit/rollback calls.
                    // Usually only for JTA: Spring synchronization might get activated here
                    // in case of a pre-existing JTA transaction.
                    var newSynchronization3 = this.transactionSynchronization != TransactionSynchronizationState.Never;
                    var status = this.NewTransactionStatus(
                        definition, transaction, true, newSynchronization3, debugEnabled, null);
                    this.DoBegin(transaction, definition);
                    this.PrepareSynchronization(status, definition);
                    return status;
                }
            }

            // Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
            if (debugEnabled)
            {
                Logger.Debug("Participating in existing transaction");
            }

            if (this.validateExistingTransaction)
            {
                if (definition.TransactionIsolationLevel != IsolationLevel.Unspecified)
                {
                    var currentIsolationLevel = TransactionSynchronizationManager.CurrentTransactionIsolationLevel;
                    if (currentIsolationLevel == null || currentIsolationLevel != definition.TransactionIsolationLevel)
                    {
                        // Constants isoConstants = DefaultTransactionDefinition.constants;
                        throw new IllegalTransactionStateException("Participating transaction with definition [" + definition + "] specifies isolation level which is incompatible with existing transaction: ");

                        // + (currentIsolationLevel != null ? isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) : "(unknown)"));
                    }
                }

                if (!definition.ReadOnly)
                {
                    if (TransactionSynchronizationManager.CurrentTransactionReadOnly)
                    {
                        throw new IllegalTransactionStateException(
                            "Participating transaction with definition [" +
                            definition + "] is not marked as read-only but existing transaction is");
                    }
                }
            }

            var newSynchronization = this.transactionSynchronization != TransactionSynchronizationState.Never;
            return this.PrepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
        }
        protected override void DoBegin(object transaction, ITransactionDefinition definition)
        {
            try
            {
                ServiceDomainTransactionObject txObject = (ServiceDomainTransactionObject)transaction;

                DoServiceDomainBegin(txObject, definition);
            }
            catch (PlatformNotSupportedException ex)
            {
                throw new TransactionSystemException("ServiceDomain failure on begin of transaction.  Platform does not support EnterpriseServices 'Services without Components'", ex);
            }
            catch (Exception e)
            {
                throw new CannotCreateTransactionException("ServiceDomain failure on begin of transaction", e);
            }
        }
        /**
         * Determine the actual timeout to use for the given definition.
         * Will fall back to this manager's default timeout if the
         * transaction definition doesn't specify a non-default value.
         * @param definition the transaction definition
         * @return the actual timeout to use
         * @see org.springframework.transaction.TransactionDefinition#getTimeout()
         * @see #setDefaultTimeout
         */

        /// <summary>The determine timeout.</summary>
        /// <param name="definition">The definition.</param>
        /// <returns>The System.Int32.</returns>
        protected int DetermineTimeout(ITransactionDefinition definition)
        {
            if (definition.TransactionTimeout != -1)
            {
                return definition.TransactionTimeout;
            }

            return this.defaultTimeout;
        }
 private void DoServiceDomainBegin(ServiceDomainTransactionObject serviceDomainTxObject, ITransactionDefinition definition)
 {
     SimpleServiceConfig serviceConfig = CreateServiceConfig(definition);
     //The context is created when we call Enter.
     serviceDomainTxObject.ServiceDomainAdapter.Enter(serviceConfig);
     if (log.IsDebugEnabled)
     {
         log.Debug("Context created. TransactionId = " + ContextUtil.TransactionId
                   + ", ActivityId = " + ContextUtil.ActivityId);
     }
 }
        /// <summary>
        /// Return a currently active transaction or create a new one.
        /// </summary>
        /// <remarks>
        /// <p>
        /// This implementation handles propagation behavior.
        /// </p>
        /// <p>
        /// Delegates to
        /// <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.DoGetTransaction"/>,
        /// <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.IsExistingTransaction"/>,
        /// and
        /// <see cref="Spring.Transaction.Support.AbstractPlatformTransactionManager.DoBegin"/>.
        /// </p>
        /// <p>
        /// Note that parameters like isolation level or timeout will only be applied
        /// to new transactions, and thus be ignored when participating in active ones.
        /// Furthermore, they aren't supported by every transaction manager:
        /// a proper implementation should throw an exception when custom values
        /// that it doesn't support are specified.
        /// </p>
        /// </remarks>
        /// <param name="definition">
        /// <see cref="Spring.Transaction.ITransactionDefinition"/> instance (can be null for
        /// defaults), describing propagation behavior, isolation level, timeout etc.
        /// </param>
        /// <exception cref="Spring.Transaction.TransactionException">
        /// In case of lookup, creation, or system errors.
        /// </exception>
        /// <returns>
        /// <see cref="Spring.Transaction.ITransactionStatus"/> representing the new or current transaction.
        /// </returns>
        public ITransactionStatus GetTransaction(ITransactionDefinition definition)
        {
            object transaction = DoGetTransaction();
            bool debugEnabled = log.IsDebugEnabled;

            if (debugEnabled)
            {
                log.Debug("Using transaction object [" + transaction + "]");
            }

            if (definition == null)
            {
                definition = new DefaultTransactionDefinition();
            }
            if (IsExistingTransaction(transaction))
            {
                // Existing transaction found -> check propagation behavior to find out how to behave.
                return HandleExistingTransaction(definition, transaction, debugEnabled);
            }

            // Check definition settings for new transaction.
            if (definition.TransactionTimeout < DefaultTransactionDefinition.TIMEOUT_DEFAULT)
            {
                throw new InvalidTimeoutException("Invalid transaction timeout", definition.TransactionTimeout);
            }

            // No existing transaction found -> check propagation behavior to find out how to proceed.
            if (definition.PropagationBehavior == TransactionPropagation.Mandatory)
            {
                throw new IllegalTransactionStateException(
                    "Transaction propagation 'mandatory' but no existing transaction found");
            }
            else if (definition.PropagationBehavior == TransactionPropagation.Required ||
                     definition.PropagationBehavior == TransactionPropagation.RequiresNew ||
                      definition.PropagationBehavior == TransactionPropagation.Nested)
            {
                object suspendedResources = Suspend(null);
                if (debugEnabled)
                {
                    log.Debug("Creating new transaction with name [" + definition.Name + "]:" + definition);
                }
                try
                {
                    bool newSynchronization = (_transactionSyncState != TransactionSynchronizationState.Never);
                    DefaultTransactionStatus status = NewTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled,
                                                                                             suspendedResources);
                    DoBegin(transaction, definition);
                    PrepareSynchronization(status, definition);
                    return status;
                }
                catch (TransactionException)
                {
                    Resume(null, suspendedResources);
                    throw;
                }
            }
            else
            {
                // Create "empty" transaction: no actual transaction, but potentially synchronization.
                bool newSynchronization = (_transactionSyncState == TransactionSynchronizationState.Always);
                return PrepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);

            }

        }
        private SimpleServiceConfig CreateServiceConfig(ITransactionDefinition definition)
        {
            SimpleServiceConfig serviceConfig = new SimpleServiceConfig();

            //TODO investigate BringYourOwnTransaction and TipUrl properties of ServiceConfig
            serviceConfig.TransactionDescription = definition.Name;

            serviceConfig.TrackingEnabled = TrackingEnabled;
            serviceConfig.TrackingAppName = TrackingAppName;
            serviceConfig.TrackingComponentName = TrackingComponentName;

            ApplyPropagationBehavior(serviceConfig, definition);

            ApplyIsolationLevel(serviceConfig, definition);
            
            // infinite==-1 would cause transactions to be aborted immediately!
            if(definition.TransactionTimeout != Timeout.Infinite)
            {
                serviceConfig.TransactionTimeout = definition.TransactionTimeout;
            }
            return serviceConfig;
        }
 protected void PrepareSynchronization(DefaultTransactionStatus status, ITransactionDefinition definition)
 {
     if (status.NewSynchronization)
     {
         TransactionSynchronizationManager.ActualTransactionActive = status.HasTransaction();
         TransactionSynchronizationManager.CurrentTransactionIsolationLevel = definition.TransactionIsolationLevel != System.Data.IsolationLevel.Unspecified ? definition.TransactionIsolationLevel : IsolationLevel.Unspecified;
         TransactionSynchronizationManager.CurrentTransactionReadOnly = definition.ReadOnly;
         TransactionSynchronizationManager.CurrentTransactionName = definition.Name;
         TransactionSynchronizationManager.InitSynchronization();
     }
 }
        protected void ApplyIsolationLevel(SimpleServiceConfig serviceConfig, ITransactionDefinition definition)
        {
            switch (definition.TransactionIsolationLevel)
            {
                    
                case System.Data.IsolationLevel.Chaos:
                    if (log.IsInfoEnabled)
                    {
                        log.Info("IsolationLevel Chaos does not have a direct counterpart in EnterpriseServices, using Any");
                    }   
                    serviceConfig.IsolationLevel = TransactionIsolationLevel.Any;
                    break;
                case System.Data.IsolationLevel.ReadCommitted:
                    serviceConfig.IsolationLevel = TransactionIsolationLevel.ReadCommitted;
                    break;
                case System.Data.IsolationLevel.ReadUncommitted:
                    serviceConfig.IsolationLevel = TransactionIsolationLevel.ReadUncommitted;
                    break;
                case System.Data.IsolationLevel.RepeatableRead:
                    serviceConfig.IsolationLevel = TransactionIsolationLevel.RepeatableRead;
                    break;
                case System.Data.IsolationLevel.Serializable:
                    serviceConfig.IsolationLevel = TransactionIsolationLevel.Serializable;
                    break;
                case System.Data.IsolationLevel.Snapshot:
                    if (log.IsInfoEnabled)
                    {
                        log.Info("IsolationLevel Snapshot does not have a direct counterpart in EnterpriseServices, using ReadCommitted.  Introduced in SqlServer 2005.  Consider using System.Transactions for transaction management instead."); 
                    }   
                    serviceConfig.IsolationLevel = TransactionIsolationLevel.ReadCommitted;  //err on the side of consistency
                    break;
                case System.Data.IsolationLevel.Unspecified:
                    serviceConfig.IsolationLevel = TransactionIsolationLevel.Any;
                    break;
            }

        }
 private DefaultTransactionStatus NewTransactionStatus(ITransactionDefinition definition,
                                       object transaction, bool newTransaction,
                                       bool newSynchronization, bool debug,
                                       object suspendedResources)
 {
     bool actualNewSynchronization = newSynchronization &&
                         !TransactionSynchronizationManager.SynchronizationActive;
     //            if (actualNewSynchronization)
     //            {
     //                TransactionSynchronizationManager.ActualTransactionActive = (transaction != null);
     //                TransactionSynchronizationManager.CurrentTransactionIsolationLevel =
     //                    definition.TransactionIsolationLevel;
     //                TransactionSynchronizationManager.CurrentTransactionReadOnly = definition.ReadOnly;
     //                TransactionSynchronizationManager.CurrentTransactionName = definition.Name;
     //                TransactionSynchronizationManager.InitSynchronization();
     //            }
     return
         new DefaultTransactionStatus(transaction, newTransaction, actualNewSynchronization, definition.ReadOnly, debug,
                                      suspendedResources);
 }
 protected void ApplyPropagationBehavior(SimpleServiceConfig serviceConfig, ITransactionDefinition definition)
 {
     if (definition.PropagationBehavior == TransactionPropagation.Required)
     {
         serviceConfig.TransactionOption = TransactionOption.Required;
     }
     else if (definition.PropagationBehavior == TransactionPropagation.RequiresNew)
     {
         serviceConfig.TransactionOption = TransactionOption.RequiresNew;
     }
     else if (definition.PropagationBehavior == TransactionPropagation.Supports)
     {
         serviceConfig.TransactionOption = TransactionOption.Supported;
     }
     else if (definition.PropagationBehavior == TransactionPropagation.NotSupported)
     {
         serviceConfig.TransactionOption = TransactionOption.NotSupported;
     }
     else if (definition.PropagationBehavior == TransactionPropagation.Never)
     {
         //TODO check the validity of this mapping
         serviceConfig.TransactionOption = TransactionOption.Disabled;
     } else
     {
         //TODO Should we throw an exception instead?
         log.Warn("The requested transaction propagation option " +
                  definition.PropagationBehavior + " is not supported.  " +
                  "Defaulting to Never(Disabled) ");
     }
 }
 /// <summary>The do begin.</summary>
 /// <param name="transaction">The transaction.</param>
 /// <param name="definition">The definition.</param>
 protected override void DoBegin(object transaction, ITransactionDefinition definition) { }
        /// <summary>
        /// Do begin.
        /// </summary>
        /// <param name="transaction">
        /// The transaction.
        /// </param>
        /// <param name="definition">
        /// The definition.
        /// </param>
        /// <exception cref="InvalidIsolationLevelException">
        /// </exception>
        /// <exception cref="CannotCreateTransactionException">
        /// </exception>
        protected override void DoBegin(object transaction, ITransactionDefinition definition)
        {
            // TODO: Figure out the right isolation level.
            if (definition.TransactionIsolationLevel != IsolationLevel.Unspecified)
            {
                throw new InvalidIsolationLevelException("AMQP does not support an isolation level concept");
            }

            var txObject = (RabbitTransactionObject)transaction;
            RabbitResourceHolder resourceHolder = null;
            try
            {
                resourceHolder = ConnectionFactoryUtils.GetTransactionalResourceHolder(this.ConnectionFactory, true);
                if (this.logger.IsDebugEnabled)
                {
                    this.logger.Debug("Created AMQP transaction on channel [" + resourceHolder.Channel + "]");
                }

                // resourceHolder.DeclareTransactional();
                txObject.ResourceHolder = resourceHolder;
                txObject.ResourceHolder.SynchronizedWithTransaction = true;
                var timeout = DetermineTimeout(definition);
                if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT)
                {
                    txObject.ResourceHolder.TimeoutInSeconds = timeout;
                }

                TransactionSynchronizationManager.BindResource(this.ConnectionFactory, txObject.ResourceHolder);
            }
            catch (AmqpException ex)
            {
                if (resourceHolder != null)
                {
                    ConnectionFactoryUtils.ReleaseResources(resourceHolder);
                }

                throw new CannotCreateTransactionException("Could not create AMQP transaction", ex);
            }
        }
Esempio n. 32
0
        /// <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)
        {
            //This is the default value defined in DefaultTransactionDefinition
            if (definition.TransactionIsolationLevel != IsolationLevel.Unspecified)
            {
                throw new InvalidIsolationLevelException("NMS does not support an isoliation level concept");
            }
            MessageTransactionObject txObject = (MessageTransactionObject) transaction;
            IConnection con = null;
            ISession session = null;
            try
            {
                con = CreateConnection();
                session = CreateSession(con);
                if (LOG.IsDebugEnabled)
                {
                    log.Debug("Created NMS transaction on Session [" + session + "] from Connection [" + con + "]");
                }
                txObject.ResourceHolder = new NmsResourceHolder(ConnectionFactory, con, session);
                txObject.ResourceHolder.SynchronizedWithTransaction = true;
                int timeout = DetermineTimeout(definition);
                if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT)
                {
                    txObject.ResourceHolder.TimeoutInSeconds = timeout;
                }
                TransactionSynchronizationManager.BindResource(ConnectionFactory, txObject.ResourceHolder);
                


            } catch (NMSException ex)
            {
                if (session != null)
                {
                    try
                    {
                        session.Close();
                    } catch (Exception)
                    {}
                }
                if (con != null)
                {
                    try
                    {
                        con.Close();
                    } catch (Exception){}
                }
                throw new CannotCreateTransactionException("Could not create NMS Transaction", ex);
            }
               
        }
        private ITransactionStatus HandleExistingTransaction(ITransactionDefinition definition, object transaction, bool debugEnabled)
        {
            //bool newSynchronization;
            if (definition.PropagationBehavior == TransactionPropagation.Never)
            {
                throw new IllegalTransactionStateException(
                    "Transaction propagation 'never' but existing transaction found.");
            }
            if (definition.PropagationBehavior == TransactionPropagation.NotSupported)
            {
                if (debugEnabled)
                {
                    log.Debug("Suspending current transaction");
                }
                object suspendedResources = Suspend(transaction);
                bool newSynchronization = (_transactionSyncState == TransactionSynchronizationState.Always);
                return
                    NewTransactionStatus(definition, null, false, newSynchronization, debugEnabled,
                                         suspendedResources);
            }

            if (definition.PropagationBehavior == TransactionPropagation.RequiresNew)
            {
                if (debugEnabled)
                {
                    log.Debug("Suspending current transaction, creating new transaction with name [" +
                              definition.Name + "]:" + definition);
                }
                object suspendedResources = Suspend(transaction);
                try
                {
                    DoBegin(transaction, definition);
                }
                catch (TransactionException beginEx)
                {
                    try
                    {
                        Resume(transaction, suspendedResources);
                    }
                    catch (TransactionException resumeEx)
                    {
                        log.Error(
                            "Inner transaction begin exception overridden by outer transaction resume exception");
                        log.Error("Begin Transaction Exception", beginEx);
                        log.Error("Resume Transaction Exception", resumeEx);
                        throw;
                    }
                    throw;
                }
                bool newSynchronization = (_transactionSyncState != TransactionSynchronizationState.Never);
                return
                    NewTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
            }
            if (definition.PropagationBehavior == TransactionPropagation.Nested)
            {
                if (!NestedTransactionsAllowed)
                {
                    throw new NestedTransactionNotSupportedException(
                        "Transaction manager does not allow nested transactions by default - " +
                        "specify 'NestedTransactionsAllowed' property with value 'true'");
                }
                if (debugEnabled)
                {
                    log.Debug("Creating nested transaction with name [" + definition.Name + "]:" + definition);
                }

                if (UseSavepointForNestedTransaction())
                {
                    DefaultTransactionStatus status =
                        NewTransactionStatus(definition, transaction, false, false, debugEnabled, null);
                    status.CreateAndHoldSavepoint(DateTime.Now.ToLongTimeString());
                    return status;
                }
                else
                {
                    DoBegin(transaction, definition);
                    bool newSynchronization = (_transactionSyncState != TransactionSynchronizationState.Never);
                    return NewTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, null);

                }
            }
            // Assumably PROPAGATION_SUPPORTS.
            if (debugEnabled) {
                log.Debug("Participating in existing transaction");
            }
            bool newSynch = (_transactionSyncState != TransactionSynchronizationState.Never);
            return NewTransactionStatus(definition, transaction, false, newSynch, debugEnabled, null);
        }
        /// <summary>Do begin.</summary>
        /// <param name="transaction">The transaction.</param>
        /// <param name="definition">The definition.</param>
        protected override void DoBegin(object transaction, ITransactionDefinition definition)
        {
            // https://jira.springsource.org/browse/SPRNET-1444 (SPRNET 2.0) has default TransactionIsolationLevel as IsolationLevel.Unspecified, letting this work. Will not work for SPRNET <= 1.3.2.
            if (definition.TransactionIsolationLevel != IsolationLevel.Unspecified)
            {
                throw new InvalidIsolationLevelException("AMQP does not support an isolation level concept");
            }

            var transactionObject = (RabbitTransactionObject)transaction;
            RabbitResourceHolder resourceHolder = null;
            try
            {
                resourceHolder = ConnectionFactoryUtils.GetTransactionalResourceHolder(this.ConnectionFactory, true);
                Logger.Debug(m => m("Created AMQP transaction on channel [{0}]", resourceHolder.Channel));

                // resourceHolder.DeclareTransactional();
                transactionObject.ResourceHolder = resourceHolder;
                transactionObject.ResourceHolder.SynchronizedWithTransaction = true;
                var timeout = this.DetermineTimeout(definition);
                if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT)
                {
                    transactionObject.ResourceHolder.TimeoutInSeconds = timeout;
                }

                TransactionSynchronizationManager.BindResource(this.ConnectionFactory, transactionObject.ResourceHolder);
            }
            catch (AmqpException ex)
            {
                if (resourceHolder != null)
                {
                    ConnectionFactoryUtils.ReleaseResources(resourceHolder);
                }

                throw new CannotCreateTransactionException("Could not create AMQP transaction", ex);
            }
        }
        /// <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)
        {
            DbProviderTransactionObject txMgrStateObject =
                (DbProviderTransactionObject)transaction;
            IDbConnection con = null;

            if (dbProvider == null)
            {
                throw new ArgumentException("DbProvider is required to be set on AdoPlatformTransactionManager");
            }

            try
            {
                if (txMgrStateObject.ConnectionHolder == null || txMgrStateObject.ConnectionHolder.SynchronizedWithTransaction)
                {
                    IDbConnection newCon = DbProvider.CreateConnection();
                    if (log.IsDebugEnabled)
                    {
                        log.Debug("Acquired Connection [" + newCon + ", " + newCon.ConnectionString + "] for ADO.NET transaction");
                    }
                    newCon.Open();

                    //TODO isolation level mgmt - will need to abstract out SQL used to specify this in DbMetaData
                    //MSDN docs...
                    //With one exception, you can switch from one isolation level to another at any time during a transaction. The exception occurs when changing from any isolation level to SNAPSHOT isolation

                    //IsolationLevel previousIsolationLevel =

                    IDbTransaction newTrans = newCon.BeginTransaction(definition.TransactionIsolationLevel);

                    txMgrStateObject.SetConnectionHolder(new ConnectionHolder(newCon, newTrans), true);

                }
                txMgrStateObject.ConnectionHolder.SynchronizedWithTransaction = true;
                con = txMgrStateObject.ConnectionHolder.Connection;

                txMgrStateObject.ConnectionHolder.TransactionActive = true;

                int timeout = DetermineTimeout(definition);
                if (timeout != DefaultTransactionDefinition.TIMEOUT_DEFAULT)
                {
                    txMgrStateObject.ConnectionHolder.TimeoutInSeconds = timeout;
                }

                //Bind transactional resources to thread
                if (txMgrStateObject.NewConnectionHolder)
                {
                    TransactionSynchronizationManager.BindResource(DbProvider,
                                                                   txMgrStateObject.ConnectionHolder);
                }

            }
                //TODO catch specific exception
            catch (Exception e)
            {
                ConnectionUtils.DisposeConnection(con, DbProvider);
                throw new CannotCreateTransactionException("Could not create ADO.NET connection for transaction", e);
            }
        }
 /// <summary>The do begin.</summary>
 /// <param name="transaction">The transaction.</param>
 /// <param name="definition">The definition.</param>
 protected override void DoBegin(object transaction, ITransactionDefinition definition)
 {
     ((ResourcelessTransaction)transaction).Begin();
 }
 protected override void DoBegin(object transaction, ITransactionDefinition definition)
 {
     ++begun;
     ++inflight;
 }
 private static TransactionScopeOption CreateTransactionScopeOptions(ITransactionDefinition definition)
 {
     TransactionScopeOption txScopeOption;
     if (definition.PropagationBehavior == TransactionPropagation.Required)
     {
         txScopeOption = TransactionScopeOption.Required;
     }
     else if (definition.PropagationBehavior == TransactionPropagation.RequiresNew)
     {
         txScopeOption = TransactionScopeOption.RequiresNew;
     }
     else if (definition.PropagationBehavior == TransactionPropagation.NotSupported)
     {
         txScopeOption = TransactionScopeOption.Suppress;
     }
     else
     {
         throw new Spring.Transaction.TransactionSystemException("Transaction Propagation Behavior" +
                                                                 definition.PropagationBehavior +
                                                                 " not supported by TransactionScope.  Use Required or RequiredNew");
     }
     return txScopeOption;
 }
        /// <summary>The get transaction.</summary>
        /// <param name="definition">The definition.</param>
        /// <returns>The Spring.Transaction.ITransactionStatus.</returns>
        public ITransactionStatus GetTransaction(ITransactionDefinition definition)
        {
            var transaction = this.DoGetTransaction();

            // Cache debug flag to avoid repeated checks.
            var debugEnabled = Logger.IsDebugEnabled;

            if (definition == null)
            {
                // Use defaults if no transaction definition given.
                definition = new DefaultTransactionDefinition();
            }

            if (this.IsExistingTransaction(transaction))
            {
                // Existing transaction found -> check propagation behavior to find out how to behave.
                return this.HandleExistingTransaction(definition, transaction, debugEnabled);
            }

            // Check definition settings for new transaction.
            if (definition.TransactionTimeout < -1)
            {
                throw new InvalidTimeoutException("Invalid transaction timeout", definition.TransactionTimeout);
            }

            // No existing transaction found -> check propagation behavior to find out how to proceed.
            if (definition.PropagationBehavior == TransactionPropagation.Mandatory)
            {
                throw new IllegalTransactionStateException("No existing transaction found for transaction marked with propagation 'mandatory'");
            }
            else if (definition.PropagationBehavior == TransactionPropagation.Required ||
                     definition.PropagationBehavior == TransactionPropagation.RequiresNew ||
                     definition.PropagationBehavior == TransactionPropagation.Nested)
            {
                var suspendedResources = this.Suspend(null);
                if (debugEnabled)
                {
                    Logger.Debug("Creating new transaction with name [" + definition.Name + "]: " + definition);
                }

                try
                {
                    var newSynchronization = this.transactionSynchronization != TransactionSynchronizationState.Never;
                    var status = this.NewTransactionStatus(definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
                    this.DoBegin(transaction, definition);
                    this.PrepareSynchronization(status, definition);
                    return status;
                }
                catch (Exception ex)
                {
                    this.Resume(null, suspendedResources);
                    throw ex;
                }
            }
            else
            {
                // Create "empty" transaction: no actual transaction, but potentially synchronization.
                var newSynchronization = this.transactionSynchronization == TransactionSynchronizationState.Always;
                return this.PrepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
            }
        }