1

Based on this article here as well as the question: Difference Between Transaction and TransactionScope we know that TransactionScope

The TransactionScope class provides a simple way to mark a block of code as participating in a transaction, without requiring you to interact with the transaction itself. A transaction scope can select and manage the ambient transaction automatically. Due to its ease of use and efficiency, it is recommended that you use the TransactionScope class when developing a transaction application.

Whereas System.Transactions.Transaction

The Transaction class contains methods used by developers implementing resource managers for enlistment. It also provides functionalities for cloning a transaction and controlling the current transaction context.

The question here is whether there is a way to chose which of the two to use. The obvious answer is to use implicit transactions if you have no reason to use explicit, but what would that reason be?

Are the explicit transactions there, only to support legacy implementations?

Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61
  • "The obvious answer is to use implicit transactions if you have no reason to use explicit," - that isn't "obvious" to me; it also isn't clear which you mean is which - I guess you mean "prefer TransactionScope unless you need Transaction"? in which case, I'd humbly disagree – Marc Gravell Jan 13 '20 at 12:59
  • 2
    Being absolutely, positively sure you never get a distributed transaction by inadvertently opening a new connection to another server would be one. In fact, when you find yourself writing a lot of `TransactionScope`s that use `TransactionScopeOptions.RequiresNew`, using explicit transactions as opposed to constantly avoiding the implicit scope may well improve maintainability. And explicit transactions are *not* legacy -- instead `TransactionScope` should be seen as a convenient, higher level API *on top of* the existing infrastructure. – Jeroen Mostert Jan 13 '20 at 13:00
  • Based on the documentation here: https://learn.microsoft.com/en-us/dotnet/api/system.transactions.transaction?view=netframework-4.8 `We recommend highly that you use the easier implicit model for development.` the `TransactionScope` is to be prefered. – Athanasios Kataras Jan 13 '20 at 13:00
  • @JeroenMostert - `TransactionScopeOptions.RequiresNew` could be needed quite a lot and even require to participate in an ambient transaction, but I see your point there. `TransactionScopeOptions.RequiresNew` with a on line single transaction would be an overkill, though I have not identified any significant performance degradation by using TransactionScope. – Athanasios Kataras Jan 13 '20 at 13:05
  • Performance is a bit of a red herring anyway, because ultimately we're talking (for the most part) transactions that happen on a database, where, no matter the method used on the client side, ultimately it'll boil down to some `BEGIN TRANSACTION` statement and most of the overhead is in I/O from actual statements anyway, not the infrastructure. (Distributed transactions make the discussion a lot more complicated, but most people don't use those.) – Jeroen Mostert Jan 13 '20 at 13:08
  • Agreed it is much more complicated with DTs, though I don't think that avoiding DT escallation is reason enough to avoid using `TransactionScope`. – Athanasios Kataras Jan 13 '20 at 13:11
  • 2
    Avoiding DT escalation is not a reason not to use `TransactionScope` in new code, but it is my #1 reason to abandon it when I do -- it's very easy to wrap a block of code in a `TransactionScope` (using the ambient transaction) and then find out that somewhere, somehow, there's a piece of low-level code that also calls out to a database where we're actually not interested in incorporating this into the main transaction. Depending on what code you're (not) at liberty to change, an explicit `Connection.BeginTransaction` can be the clearest solution, more so than creative scoping. YMMV. – Jeroen Mostert Jan 13 '20 at 13:21
  • Knowledge that seems forgotten by the year 2020: `TransactionScope` has the value of NOT requiring a transaction reference to be passed around to partake in a/the transaction. DTC promotion only comes into play when a provider necessarily performs an upgrade (such as establishing a second connection via `SqlClient`), this is not really a facet of `TransactionScope` per se. It would seem many here don't understand how transactional boundaries are traditionally defined, if you find yourself smattering `RequiresNew` everywhere you should reconsider your understanding of transactional processing. – Shaun Wilson Feb 04 '21 at 02:07

1 Answers1

1

Looking around various resources, I stumbled to the following which partially answers my question: Working with transactions in EF 6

Based on this documentation (which is mostly based on EF but limitations seem to apply anyway):

There are still some limitations to the TransactionScope approach:

Requires .NET 4.5.1 or greater to work with asynchronous methods.

  • It cannot be used in cloud scenarios unless you are sure you have one and only one connection (cloud scenarios do not support distributed transactions).
  • It cannot be combined with the Database.UseTransaction() approach of the previous sections.
  • It will throw exceptions if you issue any DDL and have not enabled distributed transactions through the MSDTC Service.

Advantages of the TransactionScope approach:

  • It will automatically upgrade a local transaction to a distributed transaction if you make more than one connection to a given database or combine a connection to one database with a connection to a different database within the same transaction (note: you must have the MSDTC service configured to allow distributed transactions for this to work).
  • Ease of coding. If you prefer the transaction to be ambient and dealt with implicitly in the background rather than explicitly under you control then the TransactionScope approach may suit you better.

Being that the first article is no longer supported and the EF 6 article is newer + the comment from @MarcGravell, I assume that the decision comes down to the advantages and disadvantages of the EF 6 article above.

Community
  • 1
  • 1
Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61