| File: System\Transactions\Oletx\DtcTransactionManager.cs | Web Access |
| Project: src\runtime\src\libraries\System.Transactions.Local\src\System.Transactions.Local.csproj (System.Transactions.Local) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.InteropServices; using System.Transactions.DtcProxyShim; namespace System.Transactions.Oletx; internal sealed class DtcTransactionManager { private readonly string? _nodeName; private readonly OletxTransactionManager _oletxTm; private readonly DtcProxyShimFactory _proxyShimFactory; private byte[]? _whereabouts; internal DtcTransactionManager(string? nodeName, OletxTransactionManager oletxTm) { _nodeName = nodeName; _oletxTm = oletxTm; _proxyShimFactory = OletxTransactionManager.ProxyShimFactory; } [MemberNotNull(nameof(_whereabouts))] private void Initialize() { if (_whereabouts is not null) { return; } OletxInternalResourceManager internalRM = _oletxTm.InternalResourceManager; bool nodeNameMatches; try { _proxyShimFactory.ConnectToProxy( _nodeName, internalRM.Identifier, internalRM, out nodeNameMatches, out _whereabouts, out ResourceManagerShim resourceManagerShim); // If the node name does not match, throw. if (!nodeNameMatches) { throw new NotSupportedException(SR.ProxyCannotSupportMultipleNodeNames); } // Give the IResourceManagerShim to the internalRM and tell it to call ReenlistComplete. internalRM.ResourceManagerShim = resourceManagerShim; internalRM.CallReenlistComplete(); } catch (COMException ex) { if (ex.ErrorCode == OletxHelper.XACT_E_NOTSUPPORTED) { throw new NotSupportedException(SR.CannotSupportNodeNameSpecification); } OletxTransactionManager.ProxyException(ex); // Unfortunately MSDTCPRX may return unknown error codes when attempting to connect to MSDTC // that error should be propagated back as a TransactionManagerCommunicationException. throw TransactionManagerCommunicationException.Create(SR.TransactionManagerCommunicationException, ex); } } internal DtcProxyShimFactory ProxyShimFactory { get { if (_whereabouts is null) { lock (this) { Initialize(); } } return _proxyShimFactory; } } internal void ReleaseProxy() { lock (this) { _whereabouts = null; } } internal byte[] Whereabouts { get { if (_whereabouts is null) { lock (this) { Initialize(); } } return _whereabouts; } } internal static uint AdjustTimeout(TimeSpan timeout) { uint returnTimeout = 0; try { returnTimeout = Convert.ToUInt32(timeout.TotalMilliseconds, CultureInfo.CurrentCulture); } catch (OverflowException caughtEx) { // timeout.TotalMilliseconds might be negative, so let's catch overflow exceptions, just in case. TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log; if (etwLog.IsEnabled()) { etwLog.ExceptionConsumed(TraceSourceType.TraceSourceOleTx, caughtEx); } returnTimeout = uint.MaxValue; } return returnTimeout; } }