Consider the following methods.
DoA()
{
using (TransactionScope scope = new TransactionScope)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(query, connection);
command.ExecuteNonReader();
DoB();
scope.Complete();
}
}
}
DoB()
{
using (TransactionScope scope = new TransactionScope)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(query, connection);
command.ExecuteNonReader();
DoC();
scope.Complete();
}
}
}
DoC()
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(query, connection);
command.ExecuteNonReader();
}
}
If we call DoA()
, do the subsequent interactions in DoB()
and DoC()
run in the context of DoA()
's transaction as it pertains to SQL Server? Does DoC() run in the context of both DoA()
and DoB()
's transactions?
(Or am I grossly misunderstanding something?)
All code logically will be a single transaction. The nested scopes don't necessarily create a new transaction (unless you use RequiresNew), so it will be a single transaction. Now, each scope must vote to complete the transaction so in your second scope if you remove the Complete
, should cause the entire transaction to rollback.
DoC will be part of the transaction as well; the ambient transaction will detect the new connection and be enlisted automatically.
Please read all of the details here which explain the behavior of enrolling in the ambient transaction and the different options Requires
, RequiresNew
, and Suppress
.
Also note that if your connections don't use EXACTLY same connection string, this will automatically promote the entire transaction to a Distributed Transaction. Just something to watch out for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With