Exemplo n.º 1
0
        /// <summary>
        /// This is the core execution function, it accept a simple functor that will accept a sqlcommand
        /// the command is created in the core of the function so it really care of all the standard
        /// burden of creating connection, creating transaction and enlist command into a transaction.
        /// </summary>
        /// <param name="functionToExecute">The delegates that really executes the command.</param>
        internal static void Execute(Action <DbCommand, DbProviderFactory> functionToExecute)
        {
            DbProviderFactory factory = GetFactory();

            using (GlobalTransactionManager.TransactionToken token = CreateConnection())
            {
                ConnectionData connectionData = (ConnectionData)token.GetFromTransactionContext(GetKeyFromConnName(String.Empty));
                try
                {
                    using (DbCommand command = factory.CreateCommand())
                    {
                        command.CommandType = CommandType.Text;
                        command.Connection  = connectionData.Connection;
                        command.Transaction = connectionData.CurrentTransaction;
                        functionToExecute(command, factory);
                    }
                }
                catch
                {
                    //There is an exception, I doom the transaction.
                    token.Doom();
                    throw;
                }
            }
        }
        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"));
        }
Exemplo n.º 3
0
        /// <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 EnlistWithoutATransactionRollback()
        {
            Action <Boolean> mock = mockRepository.CreateMock <Action <Boolean> >();

            mock(false);             //Sets the expectation
            mockRepository.ReplayAll();
            using (GlobalTransactionManager.TransactionToken token = GlobalTransactionManager.Enlist(mock))
            {
                token.Doom();
                //Do something, the important thing is that the delegate is called because we have
                //not a transaction active.
            }
        }
Exemplo n.º 5
0
 /// <summary>
 /// Execute a sqlquery.
 /// </summary>
 /// <param name="q"></param>
 /// <param name="executionCore"></param>
 public static void Execute(SqlQuery q, Action executionCore)
 {
     using (GlobalTransactionManager.TransactionToken token = CreateConnection(q.ConnectionStringName))
     {
         ConnectionData connectionData =
             (ConnectionData)token.GetFromTransactionContext(
                 GetKeyFromConnName(q.ConnectionStringName));
         try
         {
             using (q.Command)
             {
                 q.Command.Connection  = connectionData.Connection;
                 q.Command.Transaction = connectionData.CurrentTransaction;
                 q.Command.CommandText = q.Query;
                 executionCore();
             }
         }
         catch
         {
             token.Doom();
             throw;
         }
     }
 }