Reputation: 3455
Say I have 2 methods (A and B)
public void A()
{
using (var connection = Database.GetConnectionString())
using (var tran = new TransactionScope())
{
//do "A"
tran.Complete()
}
}
public void B()
{
using (var connection = Database.GetConnectionString())
using (var tran = new TransactionScope())
{
A(); //call "A"
//do "B"
tran.Complete()
}
}
As you can see, method B
need to call A
, but both A
and B
already has its own TransactionScope
, in this case, what's the correct way to pass the TransactionScope
?
My Expectation is when method A
is called, it will
-. BEGIN TRAN
-. DO "A"
-. COMMIT TRAN
when method B
is called, it will
-. BEGIN TRAN
-. DO "A"
-. DO "B"
-. COMMIT TRAN
Any help will be appreciated
Upvotes: 0
Views: 1229
Reputation: 1064324
TransactionScope
is ambient and supports logical nesting by default (aka TransactionScopeOption.Required
); so usually you don't really need to pass it anywhere - as long as you (or Dapper) open(s) the connection inside the scope: it should be included. When two such TransactionScope
are nested: committing the inner one effectively does nothing (aborting an inner one dooms the entire transaction) - committing the outer transaction commits the entire thing.
However, frankly I'd usually advise using explicit ADO.NET transactions instead of TransactionScope
, and in that case you do need to pass it in; optional parameters are your friend there.
Additionally: note that TransactionScope
is almost completely separate to BEGIN TRAN
/ COMMIT TRAN
; it is an entirely different way of representing transactions (since it needs to support distributed transactions over different systems - typically via either LTM or DTC).
Upvotes: 2