Исключение тайм-аута транзакции в консольном приложении, в котором запущены серии SP - PullRequest
1 голос
/ 11 октября 2011

У меня есть консольное приложение, в котором у меня есть несколько хранимых процедур, вызываемых внутри области транзакции, которая выглядит следующим образом.

 using (TransactionScope scope = new TransactionScope(new TransactionScopeOption(), new TimeSpan(8,0,0)))
                        {      
                            CallSPMethod1();
                            CallSPMethod2();
                            CallSPMethod3();

                            //Commit all steps in transaction scope
                            scope.Complete();
                            transactionStatus = 1;
                        }
    public static void CallSPMethod1()
            {
                try
                {
                    using (SqlConnection conn = new SqlConnection(Messages.connectionString))
                    {
                        conn.Open();

                        var sqlCommand = new SqlCommand("CallSPMethod1", conn);

                        // Set the command type that you will run.
                        sqlCommand.CommandType = System.Data.CommandType.StoredProcedure;

                        sqlCommand.Parameters.Add("@i_Execution_Batch_ID", SqlDbType.UniqueIdentifier, 16);
                        sqlCommand.Parameters[0].Value = Messages.BatchId;

                        sqlCommand.CommandTimeout = 3600;
                        // Run the SP
                        sqlCommand.ExecuteNonQuery();
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception(String.Format("Method - Common.CallSPMethod1: {0}", ex.Message), ex);
                }
            }

После выполнения в течение примерно 20-30 минут вызов frist SPзавершает, но выдает исключение вроде:

System.Transactions.TransactionException: The operation is not
valid for the state of the transaction. ---> System.TimeoutException: Transactio
n Timeout
   --- End of inner exception stack trace ---
   at System.Transactions.TransactionState.EnlistPromotableSinglePhase(InternalT
ransaction tx, IPromotableSinglePhaseNotification promotableSinglePhaseNotificat
ion, Transaction atomicTransaction)
   at System.Transactions.Transaction.EnlistPromotableSinglePhase(IPromotableSin
glePhaseNotification promotableSinglePhaseNotification)
   at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
   at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
   at System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transa
ction)
   at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transacti
on transaction)
   at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection ownin
gObject)
   at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection ow
ningConnection)
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection ou
terConnection, DbConnectionFactory connectionFactory)
   at System.Data.SqlClient.SqlConnection.Open()

Может кто-нибудь помочь мне, как решить эту проблему?

1 Ответ

0 голосов
/ 11 октября 2011

Я всегда воздерживаюсь от использования объема транзакции, так как иногда это забавно

попробуйте использовать sqltranssaction. Ваш код должен выглядеть примерно так

sqlconnection con=new sqlconnection(constr);
sqltransaction tran=con.begintransaction();
                       try {      
                            CallSPMethod1(tran);
                            CallSPMethod2(tran);
                            CallSPMethod3(tran);



                            //Commit all steps in transaction scope
                           tran.commit
                            transactionStatus = 1;
                        }
                        catch{
                         tran.rollback();
                              }
    }

    public static void CallSPMethod1(sqltransaction tr)
            {
                try
                {
                    sqlconnection con=tr.connection;
                    {
                     //do ur work here
                        }
                 }
                 catch{}
              }
...