[英]How do i use SqlTransaction across multipe methods
Let's assume we have an Object A which can be deleted an Object B which hold a forendkey from A 假设我们有一个对象A,可以将其删除,而对象B持有A的一个前键
If you want to deleted A, you have to delete the forendkey from B first and then you can delete A but if something goes wrong it should be rolled back but i also want to use the delete forendkey from B independent but at the moment i don't know how to achieve this 如果要删除A,则必须先从B删除forendkey,然后再删除A,但是如果出现问题,应回滚,但我也想独立于B使用delete forendkey,但目前我不知道不知道如何实现这一目标
my current idea : 我目前的想法:
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();
}
}
}
but like you can see this is pretty ugly 但是就像你看到的那样很难看
The call 通话
public void DeleteAfromAllB(Object a)
does not need to pass the SqlConnection as you can reference from tr.Connection. 不需要传递SqlConnection,因为可以从tr.Connection引用。 So you just need the SqlTransaction as parameter.
因此,您只需要SqlTransaction作为参数。 So for your original question, yes I think passing in the SqlTransaction is the way to go.
因此,对于您的原始问题,是的,我认为传递SqlTransaction是可行的方法。 Personally I prefer this way because you can easily trace the call stack / scope of the transaction (ie where the transaction started/finished).
我个人更喜欢这种方式,因为您可以轻松地跟踪调用堆栈/事务的范围(即事务开始/完成的位置)。
Another alternative is to use a TransactionScope. 另一种选择是使用TransactionScope。
Eg 例如
private void DeleteAfromAllB(Object a)
{
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();
}
}
}
public void DeleteAfromAllB_TopLevel(Object a)
{
using (var scope = new TransactionScope())
{
try
{
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();
}
catch (Exception)
{
//ExceptionHandling
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.