Runtime: Add System.Transactions framework

Created on 24 Aug 2015  Â·  45Comments  Â·  Source: dotnet/runtime

Please, provide support for System.Transactions. This would allow to use transactions (include distributed transactions) in .NET Core applications with WCF Services.

api-needs-work

Most helpful comment

This seems like an essential feature for .NET Core. I'm not sure why it isn't being more seriously considered as a must-have. Please add my name to the list of people who need it.

All 45 comments

Is there any indication other than "Future Milestone" as to when we can expect this functionality? I am trying to port the AMQP.NET Lite (https://github.com/Azure/amqpnetlite) library, and it has a dependency on System.Transactions. Without this library I fear that I am unable to continue my porting of AMQP.

any updates on this?

I also need support for transactions... what real world business middle tier framework would NOT support transactions, may I ask?

There are currently no plans to port this technology to .NET Core. However, this doesn't mean that we'll never port it but as it stands we haven't seen many requests for it yet.

Here is another request for it. Totally follow @trailheadtechnology argumentation.

We follow an architecture pattern where transactional boundaries are determined in the business logic layer, not the data access layer. Since the business layer is not aware of database connections, we cannot use connection based transaction APIs. As long as TransactionScope is not available in .NET Core we will have not choice but to stay with classic .NET.

Please bring this api into .Net Core. It is an essentail part of every business application I've been part of for years. It is also one of the coolest pieces of functionality in .Net.

I think this is one of must have. I am not sure how one manage distributed transaction encompassing multiple components without System.Transaction.

This seems like an essential feature for .NET Core. I'm not sure why it isn't being more seriously considered as a must-have. Please add my name to the list of people who need it.

Ehm... One thing that I never expected to be not supported. Not that I use distributed transactions extensively, but they do have their use cases, especially when data is distributed into multiple databases or other data sources.

A simple example could be users store and users data store.
Users store works with Identity server and stores User info, encrypted passwords, etc.
It usually is separated from actual user data and when we need to delete user, we want to do that in a transactional way: either delete everything or leave everything in place and fix encountered errors.

Another similar situation, just with updates: at the moment we have to update some of our entities Id format, because of changed application requirements. And data using those ids is distributed throughout quite a few data sources, which are even different types of databases. I'd like to do that in a transactional way for sure. Either update everywhere or fail and leave everything in place. And all of the databases support 2PC transactions.

But without transactions support, it's a nasty _va bank_ situation: we have to make sure the code works 100% as it is supposed and hope that no magic, nor network errors are going to happen. If anything, we have to restore backups and hope for the best up until we get it right.

I understand that most of the operations should be idempotent, but sometimes the whole data set needs to be updated in a reliable manner.

Therefore, looking at the business value transactions create, I think they are quire crucial.

Of course, if there would be alternative implementation for System.Transactions, that might be sufficient. But at the moment, I guess there is nothing out there, am I right?

Just wanted to drop another request for this. It's the only thing holding my ASP.NET project from being able to target core.

For me there are two separate aspects, both important:
1) Support for distributed transactions.
2) Support for "Ambient Transactions".

2) is important for architectural reasons, as it allows me to have my business logic define transactional boundaries without being tightly coupled to the data access layer.

Maybe the two concepts should be separated? Would allow for easier portability.

Why are we waiting?

Just realized that transaction scope was not implemented in core 1.0.0. Since I'm already in the middle of building a decent-sized app in core, is there a way to "simulate" transaction scope? Currently I have two different EF contexts (different DBs but same mssql server) and need to make sure that SaveChanges on both work (as well as some biz logic in between that needs to be correct). If either SaveChanges fails and/or biz logic is incorrect, need the entire "transaction" to be rolled back.

I'm thinking of using two explicit transactions, where one is nested inside the other. Something like the below:

using (var transactionA = contextA.Database.BeginTransaction())
{
   contextA.SaveChanges();

   // some biz logic here.  if logic fails, throws exception

   using (var transactionB = contextB.Database.BeginTransaction())
   {
      contextB.SaveChanges();
      transactionB.Commit();
   }

  transactionA.Commit();
}

Is the above ok to "simulate" transaction scope-- making sure the commits are at the very end-- until distributed transactions gets implemented?

I resolved the issues as follows

 context.Database.BeginTransaction();
 try
 {
    context.SaveChanges()
    // more logic
    context.SaveChanges();
    context.Database.CommitTransaction();
 }
 catch
 {
    context.Database.RollbackTransaction();
 }

@kiwiingenuity

Not sure if you were responding to my post but if so, that would not work for me since I have two different contexts. My code snippet can still "fail" when transactionB commits ok but then transactionA fails during a commit-- meaning I can't rollback B when A fails.

Anyway I'm going to live with this at the moment since my A transaction "shouldn't fail". Hopefully they'll get transaction scope implemented in core soon.

@moraleslos
Why wouldn't my idea work for you?
Just set up the Begin / commit / rollback on both contexts?

@kiwiingenuity

transactionB does a commit first. If that is committed successfully, then the DB gets updated and you can't rollback. Then transactionA gets committed. If that commit fails, A rolls back but not B since that was already committed. Hence the need for distributed transactions.

@moraleslos

using (var transactionA = contextA.Database.BeginTransaction())
{
   using (var transactionB = contextB.Database.BeginTransaction())
   {
         try
         {
            contextA.SaveChanges()
            // more logic
            contextB.SaveChanges();

            contextA.Database.CommitTransaction();
            contextB.Database.CommitTransaction();
         }
         catch
         {
            contextA.Database.RollbackTransaction();
            contextB.Database.RollbackTransaction();
     }
     }
 }

@kiwiingenuity

Not sure if calling rollback transaction will work here once it has already been successfully committed. So in your code, if contextA commits but then contextB fails during a commit, in your catch, contextA will fail rolling back because it has already committed. It'll probably throw an InvalidOperationException when calling rollbacktransaction on contextA. This is what I'm looking at: https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqltransaction.commit%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

I could be wrong though and I'll try to simulate that... maybe someone else can comment on this?

You need Two-Phase commit protocol for this...

I agree also, TransactionScope is critical to any serious app.

Thank you for your feedback! We are investigating including support for System.Transactions in a future version of .NET Core.

Please complete our survey: .NET Core - System.Transactions Support.

The Transactions team would like to learn more about your feature usage and scenarios so that we can best port over System.Transactions to .NET Core. Your answers will be used to help us determine functionality, API surface area and future roadmap.

As well, we are looking to engage closely with the Transactions community on specific scenarios, if you are interested in this partnership - please fill out the Contact Information on the final page of the survey.

I must agree with @kwaclaw, our Service Framework purposefully enforces transactions via TransactionScope at the Service layer, which is abstracted from the Business or Data layer. Our Business layer can call other services to save subsets of the domain object if required and the TransactionScope was perfect for ensuring that the ENTIRE series of service calls was always committed as a single unit. We were able to embed the TransactionScope in the framework and both create consistency and avoid developers "forgetting" to implement it. Currently I have not been able to figure out a solution that gives us the same functionality.

We purposefully avoided use of distributed transactions and feel that ambient transactions are much more critical.

Bottom line, we are likely to abandon our efforts to move to .Net Core if at least Ambient Transactions are not implemented.

Hi, I wanted to ask why you changed the milestone from 1.1 to 1.2 since the PR has been merged already a month ago, I was actually counting on it being released this Fall.

@joshfree, can you speak to what the milestone numbers mean?

@pgrm everything in master will make it into 1.1 at this point since 1.1 hasn't forked off of master yet.

(@joshfree, just to clarify, System.Transactions isn't in master, it's in dev/api.)

@stephentoub @pgrm everything in dev/api is slated for 1.2 at this point.

https://github.com/dotnet/corefx/milestones

https://blogs.msdn.microsoft.com/dotnet/2016/07/15/net-core-roadmap/

Should this have moved from the 1.2.0 to 1.1.0 milestone? It doesn't look like it was actually promoted to the 1.1.0 release.

@SaltyDH, yes, it should be 1.2. Thanks.

Any expected release date for v1.2 or v2, containing TransactionScope?

Thanks

v2

Latest ship details are here:
https://github.com/dotnet/core/blob/master/roadmap.md#ship-dates

Sorry to bump this, but does core 2.0 support Ambient Transactions?
It's critical component of our architecture and this is the closest issue I could find relating to it.
Information on the internet is conflicting.

@trailheadtechnology support for ambient transactions seems to be tracked by issue https://github.com/dotnet/corefx/issues/12534, which is currently set to 2.1.0 milestone, i.e. this does not seem to be included with core 2.0.

I think it's safe to say from the discussion that most people here were expecting the Transaction class to be compatible with the System.Data.SqlClient library. I don't know who's problem it is, but I get a message to the effect of 'Enlisting in Ambient transactions is not supported' when I call EnlistTransaction with this class. It doesn't look like the SqlClient library cares much for the Transaction class.

Am I missing something? Is there some other library or some other paradigm for executing a two phase commit (i.e. execute an in-memory add and an SQL add as a single unit of work)? What good is the Transaction class if it doesn't work with the DbConnection class?

I have to also ask when this will be available. Lack of ambient transactions makes it very difficult to write a proper data access architecture. Is there any way this can be included in release 2.0?

It goes deeper than just Ambient Transactions. The entire System.Transactions.Transaction class is incompatible with the System.Data.SqlClient class. At this time you can't write anything with SqlClient that involves enlisting a transaction, ambient or explicit. I've had to abandon my attempt to migrate our company's product to .NET Core over this issue: you simply can't writer a middle tier without it.

I had been patiently waiting for this in 2.0 after it was deferred from
1.x. The additional delay has serious consequences on our ability to go
live in our original timeframes, Its extremely disappointing this has been
missed!

On 24 July 2017 at 20:16, DRAirey1 notifications@github.com wrote:

It goes deeper than just Ambient Transactions. The entire
System.Transactions.Transaction class is incompatible with the
System.Data.SqlClient class. At this time you can't write anything with
SqlClient that involves enlisting a transaction, ambient or explicit.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/dotnet/corefx/issues/2949#issuecomment-317379670, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AB6pyMWpMGM6nyBNAG0csp2i53n1rvBuks5sRG7kgaJpZM4FxB_g
.

I didn't know that raw transactions don't work with the SQL Server SqlClient. MySQL transactions work fine, so I'm just missing ambient transactions:

using (MySqlConnection sql = new MySqlConnection("server=127.0.0.1;uid=root;pwd=11111111;database=test;charset=utf8mb4;SSLMode=None"))
            {
                sql.Open();
                var trx = sql.BeginTransaction();
                var cmd = sql.CreateCommand();
                cmd.Transaction = trx;
                cmd.CommandText = "insert into k set value = 'hello'";
                cmd.ExecuteNonQuery();
                //Nothing gets committed
        trx.Rollback();
            }

Try doing anything that involves an explicit transaction (something implements an IEnlistmentNotification interface) and EnlistVolatile(). These kinds of operations are critical for middle tier software.

really? nothing at all?
distributed transaction is a core functionality i think :/
using dotnet core 1.1.2

Support of distributed transactions requires a distributed transaction coordinator on the platform where you are running. For Windows we obviously have MSDTC. But we need to make modifications to the classes and interfaces to allow an alternative distributed transaction coordinator to be "plugged in" and used. Those changes still need to be designed. The idea would be to modify the existing internal classes that use MSDTC to conform to the "pluggable" model.

This is the new world of "modular .net": people begged MS to bring System.Transactions to netcore, they did, but SqlClient doesn't support SysTx. Ridiculous.
May I ask why do we need TransactionScope on a platform if it cannot be used with SqlClient?
I can understand why distributed transactions aren't supported, yes we have no a x-plat coordinator. But why ambient transactions aren't supported?!

Hello, I just want to clarify if this is not working in .net core 2.0.
I ask because someone answered this in SO by pointing this documentation https://docs.microsoft.com/en-us/dotnet/api/system.transactions.transactionscope?view=netcore-2.0

But even after upgrading my core 1.0 project to 2.0 I still can't use TransactionScope. I am a bit lost with all the issues opened (quite old ones) so just wanted to confirm that even though it is documented it does not work/exists for .net core.

Was this page helpful?
0 / 5 - 0 ratings