Uh oh!
There was an error while loading. Please reload this page.
Require global opt-in for distributed transactions - #76376
Conversation
ghost
commented
Sep 29, 2022
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
ghost
commented
Sep 29, 2022
Tagging subscribers to this area: @roji Issue DetailsThis adds a static, global TransactionManager.ImplicitDistributedTransactions flag, which must be explicitly turned on in order for distributed transactions to be supported. The reasoning here, as advocated by @ajcvickers, is that back in .NET Framework many users were unintentionally causing escalation to a distributed transaction through improper use of TransactionScope, etc. This flag protects users interested in using TransactionScope but who do not want distributed transactions; this is important as distributed transactions shouldn't be used lightly and without careful consideration (dependency on MSDTC - an external component, considerable perf impact, portability to non-Windows platforms...). Re the flag itself, TransactionManager already has global settings managing transactions. Re the name ImplicitDistributedTransactions, there's a possibility we'd introduce cross-platform distributed transactions into System.Transactions (#71769); if that happens, users will very explicitly create distributed transactions, and would not need to set this flag (hence "Implicit"). /cc @ajcvickers
|
28f3cc5 to
198054dComparestephentoub
commented
Sep 29, 2022
Is the intent here to backport this to release/7.0? |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
roji
commented
Sep 29, 2022
Yeah, this is something @ajcvickers and I just discussed, despite it being quite late. Not doing this in 7.0 would make it a breaking change later - @ajcvickers will be bringing this to tactics ASAP. |
Uh oh!
There was an error while loading. Please reload this page.
jkotas
commented
Sep 29, 2022
Can we also add this as a trimming feature flag that is off by default to allow trimming the distributed transactions code? |
ghost
commented
Sep 29, 2022
Tagging subscribers to 'linkable-framework': @eerhardt, @vitek-karas, @LakshanF, @sbomer, @joperezr Issue DetailsThis adds a static, global TransactionManager.ImplicitDistributedTransactions flag, which must be explicitly turned on in order for distributed transactions to be supported. The reasoning here, as advocated by @ajcvickers, is that back in .NET Framework many users were unintentionally causing escalation to a distributed transaction through improper use of TransactionScope, etc. This flag protects users interested in using TransactionScope but who do not want distributed transactions; this is important as distributed transactions shouldn't be used lightly and without careful consideration (dependency on MSDTC - an external component, considerable perf impact, portability to non-Windows platforms...). Re the flag itself, TransactionManager already has global settings managing transactions. Re the name ImplicitDistributedTransactions, there's a possibility we'd introduce cross-platform distributed transactions into System.Transactions (#71769); if that happens, users will very explicitly create distributed transactions, and would not need to set this flag (hence "Implicit"). /cc @ajcvickers
|
carlossanlop
commented
Sep 29, 2022
@roji this was approved by Tactics. Pleased ping me when the unresolved of the feedback is addressed so I can merge it. |
teo-tsirpanis
commented
Sep 29, 2022
roji#3 will solve the trimming issues without adding an ILLink feature switch. |
carlossanlop
commented
Sep 29, 2022
roji
commented
Oct 7, 2022
I've tried to do a manual test that the code gets trimmed, and I can't see it happening. I did this by having a minimal console program with a csproj to my locally-build System.Transactions.Local.dll with this PR's changes; running the application after publishing throws Without setting ImplicitDistributedTransactions and publishing trimmed, System.Transaction.Local.dll is 226,304. Inspecting the System.Transactions.Local.dll with DotPeek seems to show all the distributed transaction types - including DtcTransactionConnector - although these should be trimmed. Console program// #pragma warning disable IL2026// TransactionManager.ImplicitDistributedTransactions = true;// #pragma warning restore IL2026Console.WriteLine(typeof(TransactionScope).Assembly.Location);awaitusingvarconn1=newSqlConnection("Server=localhost;Database=test;User=SA;Password=Abcd5678;Connect Timeout=60;ConnectRetryCount=0;Encrypt=false");awaitusingvarconn2=newSqlConnection("Server=localhost;Database=test;User=SA;Password=Abcd5678;Connect Timeout=60;ConnectRetryCount=0;Encrypt=false");using(varscope=newTransactionScope()){conn1.Open();conn2.Open();}csproj: <ProjectSdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0-windows</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<PublishTrimmed>true</PublishTrimmed>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
</PropertyGroup>
<ItemGroup>
<PackageReferenceInclude="Microsoft.Data.SqlClient"Version="3.0.1" />
</ItemGroup>
<ItemGroup>
<ReferenceInclude="C:\projects\runtime\artifacts\bin\System.Transactions.Local\Debug\net7.0-windows\System.Transactions.Local.dll" />
</ItemGroup>
</Project> |
teo-tsirpanis
commented
Oct 7, 2022
You should check which type references |
stephentoub
commented
Oct 7, 2022
@teo-tsirpanis, when you prototyped it, did you validate everything was getting trimmed away? |
teo-tsirpanis
commented
Oct 7, 2022
Unfortunately not. 😢 I thought it would be OK since trimming warnings were unsuppressed and did not show up. |
Yeah, I don't see how this construction would enable trimming. EDIT: I see now that the object which is the choke point is only allocated from the static property setter, in which case I see how that would work as long as that property setter is never used. |
teo-tsirpanis
commented
Oct 7, 2022
I explained how (I thought) it works in roji#3 (comment). Was any of my assumptions wrong? |
teo-tsirpanis
commented
Oct 7, 2022
I wrote a tiny program that follows the same logic and it works. usingClassLibrary1;namespaceTrimTest{internalstaticclassProgram{staticvoidMain(){Console.WriteLine("Hello, World!");Call(null);}staticvoidCall(I?i)=>i?.F();}}In another library namespaceClassLibrary1{publicinterfaceI{voidF();}publicclassC:I{publicvoidF(){}}}
@roji if you can send the published trimmed app I will take a look. |
6b5e14f to
ac77f7cCompareroji
commented
Oct 8, 2022
@teo-tsirpanis sent you an email offline, thanks! Also squashed and rebased over latest release/7.0. |
teo-tsirpanis
commented
Oct 8, 2022
Thanks for the email @roji. I inspected the trimmed assemblies and The trim-unsafe code, the P/Invoke that does the COM interop is removed. Removing more code will need additional refactorings. |
@teo-tsirpanis thanks, yeah - I mistakenly looked at ITransactionConnector instead of DtcTransactionConnector, I can indeed see the latter getting trimmed (and thanks for the ILSpy tip, it's indeed very useful also for understanding who's referencing a type, keeping it from getting trimmed). However, as the actual assembly sizes show (2.5k diff), this change alone doesn't allow any significant trimming as there are other references. In order to get real benefits here, it seems that all the trimmable code would have to be refactored behind ITransactionConnector. As we're snapping for 7.0 GA on Monday, I've opened #76791 to track doing this for 8.0. @carlossanlop this is now ready to merge as-is. |
ac77f7c to
3c44295Compareroji
commented
Oct 10, 2022
/azp run |
|
You have several pipelines (over 10) configured to build pull requests in this repository. Specify which pipelines you would like to run by using /azp run [pipelines] command. You can specify multiple pipelines using a comma separated list. |
carlossanlop
commented
Oct 10, 2022
Thanks for letting me know. I saw you tried to re-run the CI but the command was incomplete. I manually re-ran the single failed leg and will merge once it finishes (assuming none of the failures look related to this change). |
carlossanlop
commented
Oct 10, 2022
CI re-run passed, all green. Approved and signed-off. Ready to merge. |
Closesdotnet#76469 (cherry picked from commit 2070def)
roji
commented
Oct 11, 2022
@carlossanlop the PR adds XML docs to the new API (ImplicitDistributedTransactions), but do I need to update the XMLs manually in https://github.com/dotnet/dotnet-api-docs? |
carlossanlop
commented
Oct 11, 2022
dotnet-api-docs is the source of truth, so yes, please add it there too. |
roji
commented
Oct 11, 2022
OK. Does the XML need to be generated first with the placeholders, or do I just creat something myself? (sorry, I really don't know much about how this all works) |
carlossanlop
commented
Oct 11, 2022
You can port the triple slash docs automatically to dotnet-api-docs using the You would use a command like this: |

This adds a static, global TransactionManager.ImplicitDistributedTransactions flag, which must be explicitly turned on in order for distributed transactions to be supported.
The reasoning here, as advocated by @ajcvickers, is that back in .NET Framework many users were unintentionally causing escalation to a distributed transaction through improper use of TransactionScope, etc. This flag protects users interested in using TransactionScope but who do not want distributed transactions; this is important as distributed transactions shouldn't be used lightly and without careful consideration (dependency on MSDTC - an external component, considerable perf impact, portability to non-Windows platforms...).
Re the flag itself, TransactionManager already has global settings managing transactions. Re the name ImplicitDistributedTransactions, there's a possibility we'd introduce cross-platform distributed transactions into System.Transactions (#71769); if that happens, users will very explicitly create distributed transactions, and would not need to set this flag (hence "Implicit").
/cc @ajcvickers
Closes#76469