tickwave
tickwave

Reputation: 3455

How to pass Dapper TransactionScope across multiple method

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

Answers (1)

Marc Gravell
Marc Gravell

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

Related Questions