Как использовать SqlTransaction для нескольких методов
Давайте предположим, что у нас есть Объект A, который может быть удален Объектом B, который содержит клавишу A от A
Если вы хотите удалить A, сначала вы должны удалить переднюю клавишу из B, а затем вы можете удалить A, но если что-то пойдет не так, ее следует откатить, но я также хочу использовать независимую кнопку удаления из B, но в данный момент я не не знаю, как этого добиться
моя текущая идея:
public void DeleteA(Object a)
{
using (SqlConnection con = new SqlConnection())
{
con.open();
using (SqlTransaction tr = con.BeginTransaction())
{
try
{
DeleteAfromAllB(a, con, tr);
using (SqlCommand cmd = new SqlCommand("STP_A_Delete", con))
{
cmd.Transaction = tr;
// some parameters
// some sort of Execute
// e.g.: cmd.ExecuteNonQuery();
}
tr.Commit();
}
catch (SqlException ex)
{
//ExceptionHandling
}
}
}
}
private void DeleteAfromAllB(Object a, SqlConnection con, SqlTransaction tr)
{
try
{
using (SqlCommand cmd = new SqlCommand("STP_B_Delete_Referenc_To_A", con))
{
cmd.Transaction = tr;
// some parameters
// some sort of Execute
// e.g.: cmd.ExecuteNonQuery();
}
}
catch (SqlException ex)
{
//ExceptionHandling
}
}
public void DeleteAfromAllB(Object a)
{
using (SqlConnection con = new SqlConnection())
{
con.open();
using (SqlTransaction tr = con.BeginTransaction())
{
DeleteAfromAllB(a,con,tr);
tr.Commit();
}
}
}
но, как вы можете видеть, это довольно некрасиво
1 ответ
Вызов
public void DeleteAfromAllB(Object a)
не нужно передавать SqlConnection, так как вы можете ссылаться на tr.Connection. Так что вам просто нужно SqlTransaction в качестве параметра. Итак, для вашего первоначального вопроса, да, я думаю, что передача в SqlTransaction - это путь. Лично я предпочитаю этот способ, потому что вы можете легко отслеживать стек вызовов / объем транзакции (то есть, где транзакция началась / закончилась).
Другой альтернативой является использование TransactionScope.
Например
private void DeleteAfromAllB(Object a)
{
try
{
using (var con = new SqlConnection())
{
con.open();
using (var cmd = new SqlCommand("STP_B_Delete_Referenc_To_A", con))
{
// some parameters
// some sort of Execute
// e.g.: cmd.ExecuteNonQuery();
}
}
catch (SqlException ex)
{
//ExceptionHandling
}
}
}
public void DeleteAfromAllB_TopLevel(Object a)
{
using (var scope = new TransactionScope())
{
DeleteAfromAllB(a);
// The Complete method commits the transaction. If an exception has been thrown,
// Complete is not called and the transaction is rolled back.
scope.Complete();
}
}