15

I want to understand what is the trade-of/downside of using TransactionScopeOption.RequiresNew on EntityFramework (w/ Sql Server 2008), what are the reasons why we should NOT use RequiresNew always.

Regards.

Akram Shahda
  • 14,655
  • 4
  • 45
  • 65
Bongo Sharp
  • 9,450
  • 8
  • 25
  • 35

2 Answers2

25

You should use Required not RequiresNew. RequiresNew means every operation will use a new transaction, even if there is an encompassing already existing transaction scope. This will certainly lead to deadlocks. Even with Required there is another serious problem with TransactionScope, namely that it creates by default a Serializable transaction, which is a horribly bad choice and yet another shortcut to deadlock hell and no scalability. See using new TransactionScope() Considered Harmful. You should always create a transaction scope with the explicit TransactionOption setting the isolation level to ReadCommitted, which a much much much more sane isolation level:

using(TransactionScope scope = new TransactionScope(
    TransactionScopeOption.Required,
    new TransactionOptions {
       IsolationLevel = IsolationLevel.ReadCommitted}))
{
   /// do work here
   ...
   scope.Complete();
}
Chris Klepeis
  • 9,783
  • 16
  • 83
  • 149
Remus Rusanu
  • 288,378
  • 40
  • 442
  • 569
  • Thanks for your answer! Then when should we used RequiresNew? – Bongo Sharp Apr 25 '11 at 15:54
  • `RequiresNew` is to be used when you want a standalone transaction, not part of the calling context transaction. In other words **never**. – Remus Rusanu Apr 25 '11 at 16:45
  • 2
    Sometimes `RequiresNew` is useful for logging or auditing that should succeed regardless of the encompasing transaction. I agree, consider carefully before using. – Brian Low Nov 28 '12 at 16:04
  • 2
    @BrianLow: But unless your logging/auditing code uses `IEnlistmentNotification` wouldn't it always log and never roll back if the outer transaction fails? – Nelson Rothermel Mar 05 '14 at 02:19
  • `RequiresNew` shouldn't be used to isolate logging/auditing from potentially aborting a transaction if say the logging code threw an exception, that's what `TransactionScope.Suppress` is designed explicitly for. – james_s_tayler May 16 '19 at 12:38
1

I just wanted to add here that in a couple certain cases the method i've written is inside a parent transaction scope that may or may not be closed with scope.Complete() in these cases I didn't want to be dependent on the parent transaction so we needed to set RequiresNew.

In general though I agree it's not necessary and should use read committed.

http://msdn.microsoft.com/en-us/library/ms172152(v=vs.90).aspx

Taryn
  • 242,637
  • 56
  • 362
  • 405
Phillip Fleischer
  • 1,023
  • 12
  • 14