diff --git a/src/libraries/System.Transactions.Local/ref/System.Transactions.Local.cs b/src/libraries/System.Transactions.Local/ref/System.Transactions.Local.cs index 2f08b176bc27b..8f92c7c0f412b 100644 --- a/src/libraries/System.Transactions.Local/ref/System.Transactions.Local.cs +++ b/src/libraries/System.Transactions.Local/ref/System.Transactions.Local.cs @@ -191,6 +191,7 @@ public static partial class TransactionManager [System.Diagnostics.CodeAnalysis.DisallowNullAttribute] public static System.Transactions.HostCurrentTransactionCallback? HostCurrentCallback { get { throw null; } set { } } public static System.TimeSpan MaximumTimeout { get { throw null; } set { } } + public static bool ImplicitDistributedTransactions { get; set; } public static event System.Transactions.TransactionStartedEventHandler? DistributedTransactionStarted { add { } remove { } } public static void RecoveryComplete(System.Guid resourceManagerIdentifier) { } public static System.Transactions.Enlistment Reenlist(System.Guid resourceManagerIdentifier, byte[] recoveryInformation, System.Transactions.IEnlistmentNotification enlistmentNotification) { throw null; } diff --git a/src/libraries/System.Transactions.Local/src/Resources/Strings.resx b/src/libraries/System.Transactions.Local/src/Resources/Strings.resx index 7e75fee595f9a..484e8520aaa0f 100644 --- a/src/libraries/System.Transactions.Local/src/Resources/Strings.resx +++ b/src/libraries/System.Transactions.Local/src/Resources/Strings.resx @@ -423,4 +423,7 @@ Distributed transactions are currently unsupported in 32-bit processes. - + + Implicit distributed transactions have not been enabled. If you're intentionally starting a distributed transaction, set TransactionManager.ImplicitDistributedTransactions to true. + + \ No newline at end of file diff --git a/src/libraries/System.Transactions.Local/src/System/Transactions/DtcProxyShim/DtcProxyShimFactory.cs b/src/libraries/System.Transactions.Local/src/System/Transactions/DtcProxyShim/DtcProxyShimFactory.cs index 0a65a8a72a18b..cf5cb38fc4121 100644 --- a/src/libraries/System.Transactions.Local/src/System/Transactions/DtcProxyShim/DtcProxyShimFactory.cs +++ b/src/libraries/System.Transactions.Local/src/System/Transactions/DtcProxyShim/DtcProxyShimFactory.cs @@ -59,10 +59,14 @@ public void ConnectToProxy( out byte[] whereabouts, out ResourceManagerShim resourceManagerShim) { - switch (RuntimeInformation.ProcessArchitecture) + if (RuntimeInformation.ProcessArchitecture == Architecture.X86) { - case Architecture.X86: - throw new PlatformNotSupportedException(SR.DistributedNotSupportedOn32Bits); + throw new PlatformNotSupportedException(SR.DistributedNotSupportedOn32Bits); + } + + if (!TransactionManager.ImplicitDistributedTransactions) + { + throw new NotSupportedException(SR.ImplicitDistributedTransactionsDisabled); } ConnectToProxyCore(nodeName, resourceManagerIdentifier, managedIdentifier, out nodeNameMatches, out whereabouts, out resourceManagerShim); diff --git a/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionManager.cs b/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionManager.cs index 7ce21c51bad23..02ebc9e29b4f5 100644 --- a/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionManager.cs +++ b/src/libraries/System.Transactions.Local/src/System/Transactions/TransactionManager.cs @@ -391,6 +391,8 @@ public static TimeSpan MaximumTimeout } } + public static bool ImplicitDistributedTransactions { get; set; } + // This routine writes the "header" for the recovery information, based on the // type of the calling object and its provided parameter collection. This information // we be read back by the static Reenlist method to create the necessary transaction diff --git a/src/libraries/System.Transactions.Local/tests/OleTxTests.cs b/src/libraries/System.Transactions.Local/tests/OleTxTests.cs index 71893a29f98bd..3e0894f4dedfb 100644 --- a/src/libraries/System.Transactions.Local/tests/OleTxTests.cs +++ b/src/libraries/System.Transactions.Local/tests/OleTxTests.cs @@ -469,6 +469,8 @@ private static void Test(Action action) return; } + TransactionManager.ImplicitDistributedTransactions = true; + // In CI, we sometimes get XACT_E_TMNOTAVAILABLE; when it happens, it's typically on the very first // attempt to connect to MSDTC (flaky/slow on-demand startup of MSDTC), though not only. // This catches that error and retries. @@ -524,7 +526,20 @@ public class OleTxFixture // this is likely due to on-demand slow startup of MSDTC. Perform pre-test connecting with retry // to ensure that MSDTC is properly up when the first test runs. public OleTxFixture() - => Test(() => + { + Test(() => + { + TransactionManager.ImplicitDistributedTransactions = false; + + using var tx = new CommittableTransaction(); + + Assert.Throws(() + => tx.EnlistDurable(Guid.NewGuid(), new TestEnlistment(Phase1Vote.Done, EnlistmentOutcome.Committed), EnlistmentOptions.None)); + }); + + TransactionManager.ImplicitDistributedTransactions = true; + + Test(() => { using var tx = new CommittableTransaction(); @@ -536,5 +551,6 @@ public OleTxFixture() tx.Commit(); }); + } } }