Как найти статус транзакции

Я использую "TransactionScope", и мне нужно просто сделать DML в коде С#, который у меня есть.

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

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

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

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

Ответ 1

Если вы посетите страницу 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

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

Внутри оператора транзакции с использованием оператора и перед вызовом 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 committed code goes here!
    }
}

Чтобы процитировать MSDN

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

Ответ 4

Как насчет:

TransactionStatus status = Transaction.Current.TransactionInformation.Status;