У меня есть проблема, и все статьи или примеры, которые я нашел, кажется, не заботятся об этом.
Я хочу сделать некоторые действия базы данных в транзакции. То, что я хочу сделать, очень похоже на большинство примеров:
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
блок, но я думаю, что это немного опасно, так как оба могут выдать несколько исключений.
Я неправильно, или большинство людей просто игнорирует этот риск? Что лучшее решение состоит в том, чтобы смочь откатывать, если исключение происходит?
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;
}
}
Образцы Microsoft, размещают begin trans вне try/catch см. эту msdn ссылку. Я предполагаю, что метод BeginTransaction должен либо выбрасывать исключение, либо начинать транзакцию, но никак не то и другое (хотя в документации не сказано, что это невозможно).
Однако, возможно, вам лучше использовать TransactionScope, который управляет многими (не очень) тяжелыми задачами за вас: this link
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;
}
}
используйте это
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 - Вы не фиксировали это в случае успешной обработки