Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

324
Views
How to enlist with a TransactionScope?

Short Version

How do i enlist in an ongoing TransactionScope?

Long Version

If you use a TransactionScope, you can create an "ambient" transaction:

using (TransactionScope scope = new TransactionScope())
{
   //...stuff happens, then you complete...

   // The Complete method commits the transaction. 
   scope.Complete();
}

What is that good for? Well, there are some classes in the .NET framework that know how to check if there is an ambient ongoing transaction by checking the static:

  • System.Transactions.Current

This lets them know that there is a transaction in progress.

For example, if you had some arbitrary database operation that otherwise didn't consider transactions:

void DropStudents()
{
   using (var cmd = connection.CreateCommand())
   {
      cmd.CommandText = "DROP TABLE Students;";
      cmd.ExecuteNonQuery();
   }
}

If you plop that in the middle of a TransactionScope:

using (TransactionScope scope = new TransactionScope())
{
   DropStudents();

   // The Complete method commits the transaction. 
   scope.Complete();
}

Suddnely your ADO.net operations are in a transaction; and can be rolled back.

Automatic BeginTranasction, Commit, and Rollback

The SqlClient library knows to check:

  • System.Transactions.Current

and automatically internally:

  • Begin a database transaction
  • Commit the database transaction when you call Scope.Complete
  • Rollback the database transaction when the scope is rolled back

And it's all just magic.

  • somehow the DbConnection gets a notification to call .Commit
  • and somehow the DbConnection gets a notification to call .Rollback

How do i do that?

I have a class that also has transactions. And rather than forcing the caller to call:

using (IContosoTransaction tx = turboEncabulator.BeginTransaction())
{
   try
   {
      turboEncabulator.UpendCardinalGrammeters();
   }
   catch (Exception ex)
   {
      tx.Rollback();
      throw;
   }
   tx.Commit();
}

It would be nice if they could just call:

turboEncabulator.UpendCardinalGrammeters();

And my code will simply check:

  • System.Transactions.Current

And if there is a transaction in progress, i will:

  • begin a transaction
  • wait for the notification to Commit
  • or wait for the notification to Rollback

But how do i do that?

How do i register myself with an ongoing TransactionScope to get these notifications?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

It's not that bad actually.

  1. Check if there is a transaction in progress by seeing if System.Transactions.Transaction.Current is assigned. If there is, Enlist in the transaction:

    //Enlist in any current transactionScope if one is active
    if (System.Transactions.Transaction.Current != null)
       System.Transactions.Transaction.Current.EnlistVolatile(this, EnlistmentOptions.None);
    
  2. And then you need to implement the four notification methods of IEnlistmentNotification:

    • void Prepare(PreparingEnlistment preparingEnlistment);
    • void Commit(Enlistment enlistment);
    • void InDoubt(Enlistment enlistment);
    • void Rollback(Enlistment enlistment);

The actual implementations are trivial boilerplate notifications:

  • Prepare: Transaction manager is asking for your vote on whether the transaction is good to be committed:
    • To vote Yes: preparingEnlistment.Prepared();
    • To vote No: preparingEnlistment.ForceRollback();
  • Commit: Do your stuff to commit and declare that you are done with your enlistment:
    • enlistment.Done();
  • InDoubt: Notification that the transaction manager lost communication with someone else involved in the transaction. Respond by letting them know you are done with the enlistment:
    • enlistment.Done();
  • Rollback: Notification that the transaction is being rolled back. Do any sort of rollback work, and let them know you're done with the enlistment:
    • enlistment.Done();

Or more fully

public void Prepare(PreparingEnlistment preparingEnlistment)
{
   //The transaction manager is asking for our vote if the transaction
   //can be committed

   //Vote "yes" by calling .Prepared:
   preparingenlistment.Prepared();

   //Vote "no" by calling .ForceRollback:
   //preparingEnlistment.ForceRollback();
}

public void Commit(Enlistment enlistment)
{
   //The transaction is being committed - do whatever it is we do to commit.

   //Let them know we're done with the enlistment.
   enlistment.Done();
}

public void InDoubt(Enlistment enlistment)
{
   //Do any work necessary when indoubt notification is received.
   //This method is called if the transaction manager loses contact with one or more participants, 
   //so their status is unknown.
   //If this occurs, you should log this fact so that you can investigate later whether any of the 
   //transaction participants has been left in an inconsistent state.

   //Let them know we're done with the enlistment.
   enlistment.Done();
}

public void Rollback(Enlistment enlistment)
{
   //If any resource manager reported a failure to prepare in phase 1, the transaction manager invokes 
   //the Rollback method for each resource manager and indicates to the application the failure of the commit.

   //Let them know we're done with the enlistment.
   enlistment.Done();
}
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!