Как найти статус транзакции - PullRequest
11 голосов
/ 30 марта 2012

Я использую «TransactionScope», и мне нужно просто сделать немного DML в коде C #, что я успешно выполнил.

Мне нужно выяснить, что каков статус транзакции , то есть успешно она выполнена или нет?

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

Я хочу перенаправить после следующего: -
scope.Complete ();
scope.Dispose ();

Пожалуйста, помогите мне в этом.

Ответы [ 4 ]

10 голосов
/ 30 марта 2012

Если вы посетите страницу MSDN для TransactionScope, вы найдете этот хорошо документированный пример:

try
{
    // Create the TransactionScope to execute the commands, guaranteeing
    // that both commands can commit or roll back as a single unit of work.
    using (TransactionScope scope = new TransactionScope())
    {
        using (SqlConnection connection1 = new SqlConnection(connectString1))
        {
            // Opening the connection automatically enlists it in the 
            // TransactionScope as a lightweight transaction.
            connection1.Open();

            // Create the SqlCommand object and execute the first command.
            SqlCommand command1 = new SqlCommand(commandText1, connection1);
            returnValue = command1.ExecuteNonQuery();
            writer.WriteLine("Rows to be affected by command1: {0}", returnValue);

            // If you get here, this means that command1 succeeded. By nesting
            // the using block for connection2 inside that of connection1, you
            // conserve server and network resources as connection2 is opened
            // only when there is a chance that the transaction can commit.   
            using (SqlConnection connection2 = new SqlConnection(connectString2))
            {
                // The transaction is escalated to a full distributed
                // transaction when connection2 is opened.
                connection2.Open();

                // Execute the second command in the second database.
                returnValue = 0;
                SqlCommand command2 = new SqlCommand(commandText2, connection2);
                returnValue = command2.ExecuteNonQuery();
                writer.WriteLine("Rows to be affected by command2: {0}", returnValue);
            }
        }

        // The Complete method commits the transaction. If an exception has been thrown,
        // Complete is not  called and the transaction is rolled back.
        scope.Complete();

    }

}
catch (TransactionAbortedException ex)
{
    writer.WriteLine("TransactionAbortedException Message: {0}", ex.Message);
}
catch (ApplicationException ex)
{
    writer.WriteLine("ApplicationException Message: {0}", ex.Message);
}

Комментарий, который содержит наибольшее значение:

Метод Complete фиксирует транзакцию. Если возникла исключительная ситуация, Complete не вызывается, и транзакция откатывается.

Итак, если не сгенерировано никаких исключений, вы можете продолжить. Поместите ваш редирект после scope.Complete(). Если выдается исключение, транзакция завершается неудачно и автоматически откатывается. Вы можете дважды проверить статус транзакции (как уже сообщали другие) после вызова на Complete() и перед перенаправлением, с помощью Transaction.Current.TransactionInformation.Status:

if (Transaction.Current.TransactionInformation.Status == TransactionStatus.Committed) 
{
    // do redirect
}
3 голосов
/ 30 марта 2012

Использование Transaction.Current.TransactionInformation.Status

Свойство Transaction.Current

Свойство Transaction.TransactionInformation

2 голосов
/ 11 апреля 2013

Лучший метод, который я нашел для наиболее эффективного / правильного захвата, заключается в следующем:

Внутри транзакции используя оператор и перед вызовом scope / Complete ().

//Register for the transaction completed event for the current transaction
Transaction.Current.TransactionCompleted += new TransactionCompletedEventHandler(Current_TransactionCompleted);

Затем создайте функцию обработчика событий следующим образом:

/// <summary>
/// Handles the TransactionCompleted event of the Current control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.Transactions.TransactionEventArgs"/> instance containing the event data.</param>
static void Current_TransactionCompleted(object sender, TransactionEventArgs e)
{
    if (e.Transaction.TransactionInformation.Status == TransactionStatus.Committed)
    {
        /// Yay it's committed code goes here!
    }
}

Цитировать MSDN

"Вы можете зарегистрироваться для этого события вместо использования изменяемого перечисления для получения информации о результате для транзакций. Параметр, передаваемый делегату TransactionCompletedEventHandler, является экземпляром Transaction. Затем можно запросить свойство TransactionInformation определенного экземпляра, чтобы получить экземпляр объекта TransactionInformation, свойство Status которого содержит состояние транзакции со значением Committed или Aborted. "

2 голосов
/ 30 марта 2012

Как насчет:

TransactionStatus status = Transaction.Current.TransactionInformation.Status;
...