public void ContextNestedWithTwoTransactionLast()
        {
            GlobalTransactionManager.BeginTransaction();
            GlobalTransactionManager.BeginTransaction();

            GlobalTransactionManager.TransactionToken token = GlobalTransactionManager.Enlist(Nope);
            GlobalTransactionManager.TransactionContext.Set("key", "test", 1);
            Assert.That(token.GetFromTransactionContext("key"), Is.EqualTo("test"));
        }
        /// <summary>
        /// This is the Connetion creation function, this function should enlist in the
        /// current transaction as well reusing the same connection for all the call
        /// inside a global transaction to consume less resources.
        /// </summary>
        /// <param name="connectionName"></param>
        /// <returns></returns>
        internal static GlobalTransactionManager.TransactionToken CreateConnection(string connectionName)
        {
            ConnectionData newConnData = null;

            if (GlobalTransactionManager.IsInTransaction)
            {
                //We are in a transaction, check if at current connection stack level there is  a connection data.
                Object connData = GlobalTransactionManager.TransactionContext.Get(GetKeyFromConnName(connectionName));
                if (null != connData)
                {
                    //We already created the connection for this database in this transaction.
                    return(GlobalTransactionManager.Enlist(DoNothing));
                }
                //There is not a transaction in the current transaction stack level, are we in nested transaction?
                if (GlobalTransactionManager.TransactionsCount > 1)
                {
                    //The only connection data valid is the one at the first level, lets check if it is present.
                    connData = GlobalTransactionManager.TransactionContext.Get(GetKeyFromConnName(connectionName), 0);
                    if (null == connData)
                    {
                        //We never created the connection data
                        newConnData = new ConnectionData(connectionName);
                        GlobalTransactionManager.TransactionContext.Set(GetKeyFromConnName(connectionName), newConnData, 0);
                        GlobalTransactionManager.Enlist(newConnData.CloseConnection, 0);
                    }
                    else
                    {
                        newConnData = (ConnectionData)connData;
                    }

                    GlobalTransactionManager.TransactionToken lasttoken = null;
                    //Now we have the connection data, we need to store this connection data in each connection that is active and
                    //that still not have start a transaction
                    for (Int32 Ix = 1; Ix < GlobalTransactionManager.TransactionsCount; ++Ix)
                    {
                        if (GlobalTransactionManager.TransactionContext.Get(GetKeyFromConnName(connectionName), Ix) == null)
                        {
                            //In this step of the stack there is no ConnectionData, store and increase the transaction
                            newConnData.BeginNestedTransaction();
                            lasttoken = GlobalTransactionManager.Enlist(newConnData.CloseConnection, Ix);
                            lasttoken.SetInTransactionContext(GetKeyFromConnName(connectionName), newConnData);
                        }
                    }
                    //Return the last token, the one corresponding to the current transaction level.
                    return(lasttoken);
                }
            }

            //We are not in nested transaction and there is not connection data, create for the first time
            newConnData = new ConnectionData(connectionName);
            GlobalTransactionManager.TransactionToken token =
                GlobalTransactionManager.Enlist(newConnData.CloseConnection);
            token.SetInTransactionContext(GetKeyFromConnName(connectionName), newConnData);
            return(token);
        }
        public void GoodTransactionIsCommitted()
        {
            Action <Boolean> mock = mockRepository.CreateMock <Action <Boolean> >();

            mock(true);             //Sets the expectation
            mockRepository.ReplayAll();
            using (GlobalTransactionManager.BeginTransaction())
            {
                GlobalTransactionManager.Enlist(mock);
            }
        }
        public void EnlistWithoutATransaction()
        {
            Action <Boolean> mock = mockRepository.CreateMock <Action <Boolean> >();

            mock(true);             //Sets the expectation
            mockRepository.ReplayAll();
            using (GlobalTransactionManager.Enlist(mock))
            {
                //Do something, the important thing is that the delegate is called because we have
                //not a transaction active.
            }
        }
        public void DoomedTransactionIsRollbacked()
        {
            Action <Boolean> mock = mockRepository.CreateMock <Action <Boolean> >();

            mock(false);             //Sets the expectation
            mockRepository.ReplayAll();
            using (GlobalTransactionManager.BeginTransaction())
            {
                GlobalTransactionManager.Enlist(mock);
                GlobalTransactionManager.DoomCurrentTransaction();
            }
        }
        public void EnlistNestedWithTwoTransactionDisposeTwo()
        {
            Action <Boolean> mock = mockRepository.CreateMock <Action <Boolean> >();

            Expect.Call(() => mock(true)).Repeat.Once();             //Sets the expectation
            mockRepository.ReplayAll();
            IDisposable first  = GlobalTransactionManager.BeginTransaction();
            IDisposable second = GlobalTransactionManager.BeginTransaction();

            GlobalTransactionManager.Enlist(mock, 0);
            GlobalTransactionManager.Enlist(mock, 1);
            second.Dispose();
        }
        public void EnlistNestedWithTwoTransaction()
        {
            Action <Boolean> mock = mockRepository.CreateMock <Action <Boolean> >();

            Expect.Call(() => mock(true)).Repeat.Twice();             //Sets the expectation
            mockRepository.ReplayAll();
            using (GlobalTransactionManager.BeginTransaction())
            {
                using (GlobalTransactionManager.BeginTransaction())
                {
                    GlobalTransactionManager.Enlist(mock, 0);
                    GlobalTransactionManager.Enlist(mock, 1);
                }
            }
        }
        public void IgnoreExceptionWhenCommitt()
        {
            Action <Boolean> mock1 = mockRepository.CreateMock <Action <Boolean> >();

            mock1(true);             //Sets the expectation
            LastCall.Throw(new ApplicationException());
            Action <Boolean> mock2 = mockRepository.CreateMock <Action <Boolean> >();

            mock2(true);             //Sets the expectation
            mockRepository.ReplayAll();
            using (GlobalTransactionManager.BeginTransaction())
            {
                GlobalTransactionManager.Enlist(mock1);
                GlobalTransactionManager.Enlist(mock2);
            }
        }
        public void ImplicitTransactionIsDoomedIfExceptionIsThrown()
        {
            Action <Boolean> mock = mockRepository.CreateMock <Action <Boolean> >();

            mock(false);             //Sets the expectation
            mockRepository.ReplayAll();
            try
            {
                using (GlobalTransactionManager.BeginTransaction())
                {
                    GlobalTransactionManager.Enlist(mock);
                    throw new ApplicationException();
                }
            }
            catch (ApplicationException)
            {
                //Ok we catch the exception but the inner using is exited inside an application handler.
            }
        }
        public void LogExceptionWhenCommitt()
        {
            Action <Boolean> mock1 = mockRepository.CreateMock <Action <Boolean> >();
            Exception        ex    = new ArgumentException();

            Expect.Call(() => mock1(true)).Throw(ex);             //Sets the expectation
            ILogger mockLogger = mockRepository.CreateMock <ILogger>();

            Expect.Call(mockLogger.ActualLevel).Repeat.Any().Return(LogLevel.Info);
            Expect.Call(() => mockLogger.LogError("", ex))
            .Constraints(RhinoIs.Anything(), RhinoIs.Equal(ex));
            mockRepository.ReplayAll();
            using (Logger.Override(mockLogger))
            {
                using (GlobalTransactionManager.BeginTransaction())
                {
                    GlobalTransactionManager.Enlist(mock1);
                }
            }
        }