Не может получить доступ к объекту SqlTransaction откатывать в блоке выгоды

У меня есть проблема, и все статьи или примеры, которые я нашел, кажется, не заботятся об этом.

Я хочу сделать некоторые действия базы данных в транзакции. То, что я хочу сделать, очень похоже на большинство примеров:

using (SqlConnection Conn = new SqlConnection(_ConnectionString))
{
    try
    {
        Conn.Open();
        SqlTransaction Trans = Conn.BeginTransaction();

        using (SqlCommand Com = new SqlCommand(ComText, Conn))
        {
            /* DB work */
        }
    }
    catch (Exception Ex)
    {
        Trans.Rollback();
        return -1;
    }
}

Но проблема состоит в том что SqlTransaction Trans объявляется в try блок. Таким образом, это не доступно в catch() блок. Большинство примеров просто делает Conn.Open() и Conn.BeginTransaction() перед try блок, но я думаю, что это немного опасно, так как оба могут выдать несколько исключений.

Я неправильно, или большинство людей просто игнорирует этот риск? Что лучшее решение состоит в том, чтобы смочь откатывать, если исключение происходит?

33
задан Marks 20 October 2015 в 04:11
поделиться

4 ответа

using (var Conn = new SqlConnection(_ConnectionString))
{
    SqlTransaction trans = null;
    try
    {
        Conn.Open();
        trans = Conn.BeginTransaction();

        using (SqlCommand Com = new SqlCommand(ComText, Conn, trans))
        {
            /* DB work */
        }
        trans.Commit();
    }
    catch (Exception Ex)
    {
        if (trans != null) trans.Rollback();
        return -1;
    }
}

или вы могли бы пойти еще чище и проще и использовать это:

using (var Conn = new SqlConnection(_ConnectionString))
{
    try
    {
        Conn.Open();
        using (var ts = new System.Transactions.TransactionScope())
        {
            using (SqlCommand Com = new SqlCommand(ComText, Conn))
            {
                /* DB work */
            }
            ts.Complete();
        }
    }
    catch (Exception Ex)
    {     
        return -1;
    }
}
56
ответ дан 27 November 2019 в 17:55
поделиться

Образцы Microsoft, размещают begin trans вне try/catch см. эту msdn ссылку. Я предполагаю, что метод BeginTransaction должен либо выбрасывать исключение, либо начинать транзакцию, но никак не то и другое (хотя в документации не сказано, что это невозможно).

Однако, возможно, вам лучше использовать TransactionScope, который управляет многими (не очень) тяжелыми задачами за вас: this link

1
ответ дан 27 November 2019 в 17:55
поделиться
using (SqlConnection Conn = new SqlConnection(_ConnectionString))
{
    try
    {
        Conn.Open();
        SqlTransaction Trans = Conn.BeginTransaction();

        try 
        {
            using (SqlCommand Com = new SqlCommand(ComText, Conn))
            {
                /* DB work */
            }
        }
        catch (Exception TransEx)
        {
            Trans.Rollback();
            return -1;
        }
    }
    catch (Exception Ex)
    {
        return -1;
    }
}
3
ответ дан 27 November 2019 в 17:55
поделиться

используйте это

using (SqlConnection Conn = new SqlConnection(_ConnectionString))
{
    SqlTransaction Trans = null;
    try
    {
        Conn.Open();
        Trans = Conn.BeginTransaction();

        using (SqlCommand Com = new SqlCommand(ComText, Conn))
        {
            /* DB work */
        }
    }
    catch (Exception Ex)
    {
        if (Trans != null)
            Trans.Rollback();
        return -1;
    }
}

BTW - Вы не фиксировали это в случае успешной обработки

6
ответ дан 27 November 2019 в 17:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: