public void PropagationRequiresNewWithExistingTransaction()
        {
            #region Mock Setup
            IServiceDomainAdapter txAdapter = (IServiceDomainAdapter)mocks.CreateMock(typeof(IServiceDomainAdapter));
            using (mocks.Ordered())
            {

                Expect.Call(txAdapter.IsInTransaction).Return(false);
                SimpleServiceConfig serviceConfig = new SimpleServiceConfig();
                ConfigureServiceConfig(serviceConfig, true);
                txAdapter.Enter(serviceConfig);

                Expect.Call(txAdapter.IsInTransaction).Return(true);
                // inner tx
                ConfigureServiceConfig(serviceConfig, false);
                serviceConfig.TransactionOption = TransactionOption.RequiresNew;
                serviceConfig.IsolationLevel = TransactionIsolationLevel.Any;
                txAdapter.Enter(serviceConfig);
                Expect.Call(txAdapter.IsInTransaction).Return(true);
                txAdapter.SetAbort();
                Expect.Call(txAdapter.Leave()).Return(TransactionStatus.Aborted);
                // innter tx aborted

                //ProcessCommit - status.GlobalRollbackOnly check
                Expect.Call(txAdapter.MyTransactionVote).Return(TransactionVote.Commit);
                //DoCommit      - status.GlobalRollbackOnly check
                Expect.Call(txAdapter.MyTransactionVote).Return(TransactionVote.Commit);

                Expect.Call(txAdapter.IsInTransaction).Return(true);
                //DoCommit      - check to call SetComplete or SetAbort
                Expect.Call(txAdapter.MyTransactionVote).Return(TransactionVote.Commit);
                txAdapter.SetComplete();

                Expect.Call(txAdapter.Leave()).Return(TransactionStatus.Commited);

            }
            #endregion

            mocks.ReplayAll();

            ServiceDomainPlatformTransactionManager tm = new ServiceDomainPlatformTransactionManager(txAdapter);
            tm.TransactionSynchronization = TransactionSynchronizationState.Always;

            TransactionTemplate tt = new TransactionTemplate(tm);
            tt.PropagationBehavior = TransactionPropagation.RequiresNew;
            tt.Execute(new PropagationRequiresNewWithExistingTransactionCallbackSD(tt));
            mocks.VerifyAll();
        }
        public override bool Equals(object obj)
        {
            if (this == obj)
            {
                return(true);
            }
            SimpleServiceConfig simpleServiceConfig = obj as SimpleServiceConfig;

            if (simpleServiceConfig == null)
            {
                return(false);
            }
            if (!Equals(transactionDescription, simpleServiceConfig.transactionDescription))
            {
                return(false);
            }
            if (!Equals(trackingEnabled, simpleServiceConfig.trackingEnabled))
            {
                return(false);
            }
            if (!Equals(trackingAppName, simpleServiceConfig.trackingAppName))
            {
                return(false);
            }
            if (!Equals(trackingComponentName, simpleServiceConfig.trackingComponentName))
            {
                return(false);
            }
            if (!Equals(transactionOption, simpleServiceConfig.transactionOption))
            {
                return(false);
            }
            if (!Equals(isolationLevel, simpleServiceConfig.isolationLevel))
            {
                return(false);
            }
            if (transactionTimeout != simpleServiceConfig.transactionTimeout)
            {
                return(false);
            }
            return(true);
        }
        public void TransactionCommit()
        {
            #region Mock Setup
            IServiceDomainAdapter txAdapter = (IServiceDomainAdapter) mocks.CreateMock(typeof (IServiceDomainAdapter));
            using (mocks.Ordered())
            {
                Expect.Call(txAdapter.IsInTransaction).Return(false);
                SimpleServiceConfig serviceConfig = new SimpleServiceConfig();
                ConfigureServiceConfig(serviceConfig, true);
                txAdapter.Enter(serviceConfig);

                //ProcessCommit - status.GlobalRollbackOnly check
                Expect.Call(txAdapter.MyTransactionVote).Return(TransactionVote.Commit);
                //DoCommit      - status.GlobalRollbackOnly check
                Expect.Call(txAdapter.MyTransactionVote).Return(TransactionVote.Commit);

                Expect.Call(txAdapter.IsInTransaction).Return(true);
                //DoCommit      - check to call SetComplete or SetAbort
                Expect.Call(txAdapter.MyTransactionVote).Return(TransactionVote.Commit);
                txAdapter.SetComplete();
                Expect.Call(txAdapter.Leave()).Return(TransactionStatus.Commited);

            }
            #endregion

            mocks.ReplayAll();

            ServiceDomainPlatformTransactionManager tm = new ServiceDomainPlatformTransactionManager(txAdapter);
            TransactionTemplate tt = new TransactionTemplate(tm);
            tm.TransactionSynchronization = TransactionSynchronizationState.Always;

            tt.Execute(new TransactionDelegate(TransactionCommitMethod));

            Assert.IsFalse(TransactionSynchronizationManager.SynchronizationActive);
            Assert.IsFalse(TransactionSynchronizationManager.CurrentTransactionReadOnly);

            mocks.VerifyAll();

        }
 /// <summary>
 /// Creates the context specified by the ServiceConfig object and pushes it onto the context stack to
 /// become the current context.
 /// </summary>
 /// <param name="config">A ServiceConfig that contains the configuration information for the services to be used within the enclosed code.</param>
 public void Enter(SimpleServiceConfig config)
 {
     ServiceConfig serviceConfig = config.CreateServiceConfig();
     ServiceDomain.Enter(serviceConfig);
 }
        public void TransactionRollback()
        {
            #region Mock Setup
            IServiceDomainAdapter txAdapter = (IServiceDomainAdapter)mocks.CreateMock(typeof(IServiceDomainAdapter));
            using (mocks.Ordered())
            {

                Expect.Call(txAdapter.IsInTransaction).Return(false);
                SimpleServiceConfig serviceConfig = new SimpleServiceConfig();
                ConfigureServiceConfig(serviceConfig, true);
                txAdapter.Enter(serviceConfig);
                Expect.Call(txAdapter.IsInTransaction).Return(true);
                txAdapter.SetAbort();
                Expect.Call(txAdapter.Leave()).Return(TransactionStatus.Commited);

            }
            #endregion

            mocks.ReplayAll();

            ServiceDomainPlatformTransactionManager tm = new ServiceDomainPlatformTransactionManager(txAdapter);
            tm.TransactionSynchronization = TransactionSynchronizationState.Always;

            TransactionTemplate tt = new TransactionTemplate(tm);

            Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");

            Exception ex = new ArgumentException("test exception");
            try
            {
                tt.Execute(new TransactionRollbackTxCallback(ex));
                Assert.Fail("Should have thrown exception");
            }
            catch (ArgumentException e)
            {
                Assert.AreEqual(ex, e);
            }

            Assert.IsTrue(!TransactionSynchronizationManager.SynchronizationActive, "Synchronizations not active");


            mocks.VerifyAll();
        }
        private SimpleServiceConfig ConfigureServiceConfig(SimpleServiceConfig serviceConfig, bool standardIsolationAndProp)
        {
            serviceConfig.TransactionDescription = null;

            serviceConfig.TrackingEnabled = true;
            serviceConfig.TrackingAppName = "Spring.NET";
            serviceConfig.TrackingComponentName = "ServiceDomainPlatformTransactionManager";
            if (standardIsolationAndProp)
            {
                serviceConfig.TransactionOption = TransactionOption.Required;
                serviceConfig.IsolationLevel = TransactionIsolationLevel.ReadCommitted;
            }
            return serviceConfig;

        }
        /// <summary>
        /// Creates the context specified by the ServiceConfig object and pushes it onto the context stack to
        /// become the current context.
        /// </summary>
        /// <param name="config">A ServiceConfig that contains the configuration information for the services to be used within the enclosed code.</param>
        public void Enter(SimpleServiceConfig config)
        {
            ServiceConfig serviceConfig = config.CreateServiceConfig();

            ServiceDomain.Enter(serviceConfig);
        }
 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) ");
     }
 }
        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 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;
        }