dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.07k stars 4.69k forks source link

Cross-platform distributed transactions #71769

Open roji opened 2 years ago

roji commented 2 years ago

715 tracks porting the .NET Framework distributed transaction support over to modern .NET. Unfortunately, that support is tightly coupled to the Windows MSDTC service (and the OleTx protocol), so this works on Windows only. This issue tracks enabling distributed transactions in a cross-platform way. We are currently gauging user interest in this; if this is something you want, please upvote.

paillave commented 2 years ago

This feature is dramatically useful on a cross-platform target since docker takes more place every day in infrastructures. At my side, I don't use WCF since ages, but TransactionScope remains extremely important when dealing with multiple Dbs, or simply to manage transaction in a simple and generic way.

roji commented 2 years ago

I've discussed this with various people, and there seems to be a trend away from 2-phase-commit distributed transactions in new applications utilizing cloud-native and microservice architectures. The alternatives are typically compensation-based patterns (e.g. Sagas), which allow some degree of eventual consistency in the system, but do not require a centralized, highly-available transaction manager, and do not introduce the additional dependencies and latency that 2PC does.

For more info on why 2PC may not be the right choice for the cloud, I recommend reading this. For a good architectural comparison of 2PC vs. compensation strategies, I recommend this post and this one (thanks to @scoriani for these).

Note that my intent isn't to start a big discussion on 2PC vs. Sagas on this issue - that's better done elsewhere. I do understand that Docker is a reason why cross-platform is more important; at this point we want to gauge how many users are interested in this, and why also why the alternatives (e.g. Sagas) aren't viable for their situation.

ImGonaRot commented 2 years ago

@roji I think you meant to say (https://github.com/dotnet/runtime/issues/715 is for gauging that interest) since it was created back in 2019 and has lots of user comments versus https://github.com/dotnet/runtime/issues/71769 which was just created 19 hours ago. I am a .NET contractor for several companies, one with a 100+ developers, that still use MSDTC for distributed transactions across multiple MS SQL servers. They do use some .NET Core for smaller projects but will be stuck with .NET 4.x framework for their main websites and EDI engines since those require heavy use of distributed transactions with MSDTC. As long as MS SQL server can use MSDTC for distributed transactions, I think you will find a lot of the bigger shops that use multiple MS SQL servers will sticking with good old ADO.NET / MSDTC / distributed transactions. I know it is Windows only but I'm not sure why MS would abandon a great key feature of MS SQL. That is just my opinion though. I do hope some day it is added to .NET 7+.

roji commented 2 years ago

I think you meant to say (https://github.com/dotnet/runtime/issues/715 is for gauging that interest) since it was created back in 2019 and has lots of user comments versus https://github.com/dotnet/runtime/issues/71769 which was just created 19 hours ago.

The problem is that #715 was generally about supporting distributed transactions in .NET Core; it's not clear whether people voting on it are interested in simply moving existing applications from .NET Framework to Core - on Windows (that's what we aim to enable in .NET 7.0), or whether they're looking for cross-platform support. I suspect that a lot of the interest is about moving away from .NET Framework, and much less is about being able to move from Windows to Linux/Mac. This is why this separate issue now explicitly tracks cross-platform support, as opposed to Windows-only support.

paillave commented 2 years ago

What I'm going to say may sound crazy, but I'll give it a try: As Microsoft is a large powerful company, is it crazy to imagine that a new standard protocol is created for 2PC? This protocol would be simple enough to permit to any DB engine to be updated to support it. Then Microsoft could start to embed it in the DB engine it supports: SqlServer, CosmoDb, even Postgre... I know this sounds like quite a journey ( 🀣 ) but this is a very useful and powerful pattern that needs an influent actor such as Microsoft to deal with this large scale problem.

scoriani commented 2 years ago

Let me clarify: Microsoft is not "abandoning" 2PC and MSDTC, period! This is and will be supported by SQL Server on both Windows and Linux deployments across the entire stack. That said, as the industry recognise (see the articles linked above), 2PC doesn't really cope with cloud native development and architectures so, for those scenarios, we're not really going to promote this approach. Hope this clarifies.

roji commented 2 years ago

Thanks for the clarification @scoriani. Yes; we're assuming that cross-platform supported would mainly be to support cloud-native deployments, but in those deployments 2PC is generally considered problematic (see the articles above). This is why we're looking to understand whether people are actually interested this. We're still committed to supporting 2PC and MSDTC on Windows, which is what we're targeting for .NET 7.0.

@paillave there's no need to invent a new protocol for 2PC; XA already exists and is well-supported across databases and transaction managers. If we did go ahead and implement cross-platform distributed transactions, that's what we'd build upon.

rwasef1830 commented 2 years ago

Is the transaction scope API pluggable ? If not, can it at least be made with a provider model to allow others to implement an xa based transaction scope support ?

The case I need is the simple synchronization between 2 postgres databases and two phase commit.

On Fri, 8 Jul 2022, 2:43 pm Shay Rojansky, @.***> wrote:

Thanks for the clarification @scoriani https://github.com/scoriani. Yes; we're assuming that cross-platform supported would mainly be to support cloud-native deployments, but in those deployments 2PC is generally considered problematic (see the articles above). This is why we're looking to understand whether people are actually interested this. We're still committed to supporting 2PC and MSDTC on Windows, which is what we're targeting for .NET 7.0.

@paillave https://github.com/paillave there's no need to invent a new protocol for 2PC; XA already exists and is well-supported. If we did go ahead and implement cross-platform distributed transactions, that's what we'd build upon.

β€” Reply to this email directly, view it on GitHub https://github.com/dotnet/runtime/issues/71769#issuecomment-1178946967, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABDK5PNYJLN54VQADTK3NEDVTAPAZANCNFSM526BXHJQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

roji commented 2 years ago

@rwasef1830 System.Transactions (TransactionScope) currently isn't pluggable in terms of the transaction manager - it's currently mostly hard-wired to using MSDTC. What you're say basically amounts to implementing cross-platform distributed transactions, as I've described above. It would roughly mean the following (this isn't exhaustive):

The above is, well, far from trivial, and most probably not something one can simply do as a 3rd-party thing.

Note that Npgsql did support distributed transactions for PostgreSQL on .NET Framework, via Sys.Tx. However, it did so as a volatile RM, meaning that recovery wasn't implemented; this was mainly because of the incompatible recovery flow mentioned above (see https://github.com/npgsql/npgsql/issues/1378).

PS As a sort of hack, if you're just looking to do 2PC without recovery, you can manually send PostgreSQL PREPARE TRANSACTION and COMMIT PREPARED from your application. This should work, but if there's a crash in between, you'll have to somehow deal with it yourself.

swh-cb commented 2 years ago

@roji Do you know if it's technically possible to deploy MSDTC as a stand-alone service (i.e. without SQL Server) on platforms other than Windows in the future? If MSDTC would provide a new, platform-independent (HTTP?) API as an alternative to the existing COM interface for this stand-alone service, .NET could continue to use OleTx transactions with MSDTC for all platforms. This would have the advantage that the existing database drivers doesn't need to be changed. If an application wants to use a 3rd party XA transaction manager, .NET can still map the XA transaction to an internal OleTx transaction using the XA mapping functionality provided by MSDTC. For example the ODBC driver for SQL server can use a remote MSDTC (that is connected to the SQL server) to coordinate XA transactions platform-independently on Windows, Linux and macOS.

By the way, distributed transactions are already possible for cloud-native deployments if you deploy your apps to Azure with Azure SQL only. Azure SQL supports distributed transactions (called elastic transactions) in a limited way using a non-MSDTC transaction coordinator. For this to work in .NET, the SQL client performs a PSPE enlistment with a custom promoter type on Azure. Custom promoter types were introduced in .NET Framework 4.6.1 and ported to .NET Core to allow external non-MSDTC transaction managers in System.Transactions for delegated transactions only.

roji commented 2 years ago

@swh-cb I'm not related to MSDTC in any way, so I can't speak to their plans. But as far as I know, MSDTC definitely doesn't run on non-Windows platforms - and I'd be surprised if there are plans to change that. It's purely a Windows service. So a future HTTP-based OleTx interface wouldn't really help, unless you're OK with having a Windows server somewhere just for that.

It's unfortunately very likely that drivers will need to change in any case; as I wrote above, the Sys.Tx model has some incompatibilities with the XA approach, especially around recovery and the management of the transaction ID (XID in XA).

Yeah, I'm well-aware of the Azure SQL elastic transaction mechanism. That's a pretty unique model, in which the (first) database itself acts as DTC. Sys.Tx was changed specifically to support that model, and you can't manage any non-Azure resources in the distributed transaction (e.g. a queue). Though interestingly enough, since there's no dependency on MSDTC, it should be possible to do those transactions from non-Windows platforms. In any case, I don't think this model is very relevant for the general cross-platform 2PC conversation.

paillave commented 2 years ago

@roji Maybe @swh-cb has a point here. It might be easier and less risky to make some sort of multi platform MSDC (in .NET core if performances can allow it). Because indeed, the plan you have in mind not only looks like a daunting duty, but it seems very risky (as many key components have to be touched in their core), and very complicated to manage (as there are as many teams as there are components involved in all this matter, it looks like something like this can be done in 5 years min and has many chances to be abandoned at the end of the day). Making an opensource multiplatform replacement of MSDTC in .NET seems to be the most graceful way to overcome your problem at then end of the day. Therefore at your side, the work would be limited to ensure to call the right transaction manager depending on the runtime context. Do I sound too crazy?

roji commented 2 years ago

First, creating a new transaction manager is well out of scope of this discussion. A DTC is a complex piece of software with very strong reliability requirements; building a new one (and possibly porting MSDTC to Linux) is very likely to be more work than the above cross-platform plan. In any case, battle-proven DTCs already exist out there, so I don't think we should be writing another one.

Second, a cross-platform MSDTC would not be a magic bullet solution here. As I wrote above, the Sys.Tx design is incompatible with some XA aspects, especially around recovery and transaction ID management. This means that while you'd be able to do 2PC against SQL Server run on Linux, it would still be problematic - and possibly impossible - to implement full 2PC against other databases (e.g. MySQL, PostgreSQL).

Finally, it doesn't seem appropriate to require anyone using distributed transactions to use only one transaction manager; it should be possible for people to use whatever it is that fits their needs.

To summarize, cross-platform 2PC support in .NET would mean adopting the XA protocol, which is already supported across a wide array of of both databases/queues, and transaction manager implementations. This would unfortunately require changes in both Sys.Tx and existing database drivers.

paillave commented 2 years ago

I don't really know what you have in mind when you mention the "scope". I get that the scope of this post is to have a vote whether TransactionScope shall be multiplatform or not. As a matter of a fact, the only scope I'm interested in is to have a simple 2PC tooling working on every platform. The way it is done behind the scenes really doesn't matter to me πŸ˜„

If my understanding is correct (I may be wrong), what you say is the following:

If what I mention above is correct... There is obviously something that must be addressed at the end of the day. I understand this is a lot of work and very risky actions. But I believe that at some point, in years maybe, it is clearly obvious that MSDTC and drivers will have to respect this protocol.

Sadly, it looks like this will never happen, as it took 20 years for something as crucial and popular as a web browser to fully comply with standards... so I can't even imagine how long it will take for a 2PC server 😞

I believe you won't have many votes to request to have this done as most people will choose the easy and quick solution (not using docker) and will never have the patience to wait that Microsoft does the work.

roji commented 2 years ago

The way it is done behind the scenes really doesn't matter to me

I do understand that, and you're right that users shouldn't care how the solution is implemented. But it's important to understand that we're discussing this within the scope of .NET, where MSDTC is a completely different component, which is part of Windows. Any approach which relies on MSDTC being ported to non-Windows is, pragmatically speaking, most probably a non-starter. In addition, as I wrote above, we don't want the end result to be dependent on MSDTC, but rather to support other distributed transaction managers. That's why I suggest leaving MSDTC out of the cross-platform discussion.

paillave commented 2 years ago

In addition, as I wrote above, we don't want the end result to be dependent on MSDTC, but rather to support other distributed transaction managers. That's why I suggest leaving MSDTC out of the cross-platform discussion.

I could not agree more, and this is this very conclusion that leads me to think that I am not going to see this proper solution to be implemented soon regarding the massive and risky work that must be done.

swh-cb commented 2 years ago

@roji Thank you for the detailed explanation why in the long term the XA protocol should be integrated in .NET, similar to Java.

But as far as I know, MSDTC definitely doesn't run on non-Windows platforms - and I'd be surprised if there are plans to change that. It's purely a Windows service.

Are you sure? So far I was of the opinion that MSDTC is already embedded in the SQL Server and has been running on Linux since SQL Server 2017. This is also what the SQL Server documentation says. So I thought that before teaching .NET the XA protocol, maybe it should be considered to extract the MSDTC component as a stand-alone service in Linux. This is of course not the scope of this .NET issue and should be discussed with the MSDTC/SQL Server team. Maybe there is also a solution for the XA/OleTx incompatibilities you mentioned.

roji commented 2 years ago

@swh-cb even if this were possible (and I don't know if it is), as I wrote above that still excludes other databases (PostgreSQL, MySQL) and other transaction managers. So I still don't think it makes sense as a general strategy for cross-platform distributed transactions.

llermanos commented 2 years ago

In our case, we have business applications developed from .NET 3.5 that use WCF with ONPREMISE distributed transactions and this is not going to change due to the business needs of our clients. Solutions that have more than 150+ assemblies and have around more than 15 years of work.

Currently we have been able to migrate most services and applications to .NET 6, but the transactional layers have been stuck in .NET 4.8 and .Net Standard.

We don't need it to be multiplatform or cloud either, because with Windows it covers our needs and the cloud is not an option. The best option in our case is for it to be a Windows-only feature and to be able to migrate all projects to .NET 6.

roji commented 2 years ago

@llermanos thanks for the feedback - that's definitely a scenario we had in mind, and that's why we're planning on doing #715 for the upcoming 7.0 release (am actively working on that). I may need some help confirming that WCF works well here, any chance you could help out with a minimal .NET Core console program that would represent your scenario?

llermanos commented 2 years ago

@roji

Of course I can help. I'm going to need a couple of days to prepare a demo. What I'm not sure about in a scenario where there is WCF with TransactionFlow=Enabled/Required at another end might work. I know that CoreWCF doesn't support TransactionFlow yet, I should do some more research.

Scenario 1: .NET6 Console App w/EF 6.4 (Transaction Scope) .NET4.8 WCF Service w/EF 6.4 OR ADO.

Scenario 2: .NET6 Console App w/EF 6.4 (Transaction Scope) EF/ADO .NET6 Console App EF 6.4 (Transaction Scope) EF/ADO

roji commented 2 years ago

@llermanos thanks.

At the moment I'm indeed concentrating on the scenario where multiple database connections are enlisted to the same transaction (e.g. via TransactionScope) in the same application. I did bring the entire support over from .NET Framework, so in principle, there's good reason to believe WCF scenarios would work as well; but proper testing is important here.

I'll be focusing on the PR in the coming days, to get it merge within the next two weeks. Any info/samples/help would be appreciated.

BTW let's continue this conversation over on #715, since this issue tracks the cross-platform support. I'll minimize our comments here.

alevenelli commented 2 years ago

Guys, good morning.

I can't believe we won't have this feature (2PC) supported by .Net7 or .Net8 running on Linux. We know that in microservices architectures, we must use SAGA or other processes, but the fact is that if this resource does not exist for .Net, every time we start factoring a monolith, we will go to Java containers so that we don't have to initially create all the compensation process that does not exist in each object/method of the application. Please support me if I'm right and correct me if I'm wrong.

paillave commented 2 years ago

I can't believe we won't have this feature (2PC) supported by .Net7 or .Net8 running on Linux. We know that in microservices architectures, we must use SAGA or other processes, but the fact is that if this resource does not exist for .Net, every time we start factoring a monolith, we will go to Java containers so that we don't have to initially create all the compensation process that does not exist in each object/method of the application. Please support me if I'm right and correct me if I'm wrong.

@alevenelli Many of us would love to have this feature for NET generally speaking. But as mentioned above, sometimes, history is too heavy to be changed very quickly. It happens that Microsoft initially thought all its tools for Windows platform, moreover at a time when distributed transactions standards were not precise enough. Microsoft developed its own distributed transaction server for windows, it worked (and still works) gracefully. You must bear in mind that when DCOM, the ancestor or COM+ started to be developed right when linux was just released in V1.0! Now, almost 30 years later, linux became very important (I work myself exclusively on linux since 4 years!), NET became open source as well, and Microsoft invests more and more into linux platform. But changing something that is as sensitive and central into Windows OS like COM+ is a great risk and the strategy to move forward must be cautiously chosen. Things are not always going as fast as we would expect, but obviously, if we trust what @roji has in mind to move forward, at some point, things should be finally done in a very graceful way regarding 2PC implementation.

bxjg1987 commented 2 years ago

η›Έε½“η»™εŠ›ηš„η‰ΉεΎ

birojnayak commented 1 year ago

I see lots of votes (thank you for that).. It would be really helpful for everyone to know type of Apps and what's final distro (OS target) people are looking to host.

wertzui commented 1 year ago

I have the need to use a distributed transaction targeting multiple databases (SQL Server). I need to modify 2 tables in those databases and this must happen atomically. The app is running in a Debian Docker Container.

xXAvoraXx commented 1 year ago

Problem solved for .NET 7 Oracle.EntityFrameworkCore linux distribution?

roji commented 1 year ago

@xXAvoraXx not sure what you mean; as per this issue, .NET currently does not support distributed transactions on any non-Windows platform.

xXAvoraXx commented 1 year ago

I am developing web api with .NET 7, we use oracle as database. I use transaction scope while performing entityframework operations, but it does not allow distributed transactions.

roji commented 1 year ago

That's correct. You can use TransactionScope with distributed transactions, but if you really do need distributed transactions across multiple databases, you'll have to use Windows because of the current dependency on the MSDTC.

xXAvoraXx commented 1 year ago

When will support for cross-platforms be available?

roji commented 1 year ago

@xXAvoraXx there are no current plans to implement this, as it would require a very big investment across the entire stack. For now we're using this issue to gather feedback.

xXAvoraXx commented 1 year ago

Is there a third party open source library that solves this problem?

roji commented 1 year ago

Not as far as I know.

dormendo commented 9 months ago

Hello!

I'm working on enterprise project which manages master data and allows users to create new data tables with non-unified structure. The server can work on SQL Server, Oracle or postgres DBMS. The metadata service implements its own volatile transaction managers for in-memory metadata cache. This cache should store absolutely actual metadata. And we need to create authorization rules in the same transaction that created a new data storage table. Authorization rules must have an ability to be stored in a special DB resource. So we really need such conceptions as transaction resources and 2 phase commit. I know we could rewrite this logic, but we completely satisfied with it and would love not to lose it. Going crossplatform causing our project to lose some Windows-only functionality like OLEDB import and export of data, Windows-based impersonation, so on. But nevertheless we would like to have transaction resources and 2PC.

roji commented 9 months ago

@dormendo you can do 2PC since .NET 7.0, but you have to be on Windows to do it, because of the dependency on MSDTC.