public CommittableTransaction() { }
public CommittableTransaction(System.TimeSpan timeout) { }
public CommittableTransaction(System.Transactions.TransactionOptions options) { }
- object System.IAsyncResult.AsyncState { get { throw null; } }
+ object? System.IAsyncResult.AsyncState { get { throw null; } }
System.Threading.WaitHandle System.IAsyncResult.AsyncWaitHandle { get { throw null; } }
bool System.IAsyncResult.CompletedSynchronously { get { throw null; } }
bool System.IAsyncResult.IsCompleted { get { throw null; } }
- public System.IAsyncResult BeginCommit(System.AsyncCallback asyncCallback, object asyncState) { throw null; }
+ public System.IAsyncResult BeginCommit(System.AsyncCallback? asyncCallback, object? asyncState) { throw null; }
public void Commit() { }
public void EndCommit(System.IAsyncResult asyncResult) { }
}
Automatic = 1,
Full = 2,
}
- public delegate System.Transactions.Transaction HostCurrentTransactionCallback();
+ public delegate System.Transactions.Transaction? HostCurrentTransactionCallback();
[System.Runtime.InteropServices.InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIUnknown)]
public partial interface IDtcTransaction
{
}
public partial interface ITransactionPromoter
{
- byte[] Promote();
+ byte[]? Promote();
}
public partial class PreparingEnlistment : System.Transactions.Enlistment
{
internal PreparingEnlistment() { }
public void ForceRollback() { }
- public void ForceRollback(System.Exception e) { }
+ public void ForceRollback(System.Exception? e) { }
public void Prepared() { }
public byte[] RecoveryInformation() { throw null; }
}
{
internal SinglePhaseEnlistment() { }
public void Aborted() { }
- public void Aborted(System.Exception e) { }
+ public void Aborted(System.Exception? e) { }
public void Committed() { }
public void InDoubt() { }
- public void InDoubt(System.Exception e) { }
+ public void InDoubt(System.Exception? e) { }
}
public sealed partial class SubordinateTransaction : System.Transactions.Transaction
{
public partial class Transaction : System.IDisposable, System.Runtime.Serialization.ISerializable
{
internal Transaction() { }
- public static System.Transactions.Transaction Current { get { throw null; } set { } }
+ public static System.Transactions.Transaction? Current { get { throw null; } set { } }
public System.Transactions.IsolationLevel IsolationLevel { get { throw null; } }
public System.Guid PromoterType { get { throw null; } }
public System.Transactions.TransactionInformation TransactionInformation { get { throw null; } }
- public event System.Transactions.TransactionCompletedEventHandler TransactionCompleted { add { } remove { } }
+ public event System.Transactions.TransactionCompletedEventHandler? TransactionCompleted { add { } remove { } }
public System.Transactions.Transaction Clone() { throw null; }
public System.Transactions.DependentTransaction DependentClone(System.Transactions.DependentCloneOption cloneOption) { throw null; }
public void Dispose() { }
public bool EnlistPromotableSinglePhase(System.Transactions.IPromotableSinglePhaseNotification promotableSinglePhaseNotification, System.Guid promoterType) { throw null; }
public System.Transactions.Enlistment EnlistVolatile(System.Transactions.IEnlistmentNotification enlistmentNotification, System.Transactions.EnlistmentOptions enlistmentOptions) { throw null; }
public System.Transactions.Enlistment EnlistVolatile(System.Transactions.ISinglePhaseNotification singlePhaseNotification, System.Transactions.EnlistmentOptions enlistmentOptions) { throw null; }
- public override bool Equals(object obj) { throw null; }
+ public override bool Equals(object? obj) { throw null; }
public override int GetHashCode() { throw null; }
public byte[] GetPromotedToken() { throw null; }
- public static bool operator ==(System.Transactions.Transaction x, System.Transactions.Transaction y) { throw null; }
- public static bool operator !=(System.Transactions.Transaction x, System.Transactions.Transaction y) { throw null; }
+ public static bool operator ==(System.Transactions.Transaction? x, System.Transactions.Transaction? y) { throw null; }
+ public static bool operator !=(System.Transactions.Transaction? x, System.Transactions.Transaction? y) { throw null; }
public System.Transactions.Enlistment PromoteAndEnlistDurable(System.Guid resourceManagerIdentifier, System.Transactions.IPromotableSinglePhaseNotification promotableNotification, System.Transactions.ISinglePhaseNotification enlistmentNotification, System.Transactions.EnlistmentOptions enlistmentOptions) { throw null; }
public void Rollback() { }
- public void Rollback(System.Exception e) { }
+ public void Rollback(System.Exception? e) { }
public void SetDistributedTransactionIdentifier(System.Transactions.IPromotableSinglePhaseNotification promotableNotification, System.Guid distributedTransactionIdentifier) { }
void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext context) { }
}
{
public TransactionAbortedException() { }
protected TransactionAbortedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public TransactionAbortedException(string message) { }
- public TransactionAbortedException(string message, System.Exception innerException) { }
+ public TransactionAbortedException(string? message) { }
+ public TransactionAbortedException(string? message, System.Exception? innerException) { }
}
- public delegate void TransactionCompletedEventHandler(object sender, System.Transactions.TransactionEventArgs e);
+ public delegate void TransactionCompletedEventHandler(object? sender, System.Transactions.TransactionEventArgs e);
public partial class TransactionEventArgs : System.EventArgs
{
public TransactionEventArgs() { }
- public System.Transactions.Transaction Transaction { get { throw null; } }
+ public System.Transactions.Transaction? Transaction { get { throw null; } }
}
public partial class TransactionException : System.SystemException
{
public TransactionException() { }
protected TransactionException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public TransactionException(string message) { }
- public TransactionException(string message, System.Exception innerException) { }
+ public TransactionException(string? message) { }
+ public TransactionException(string? message, System.Exception? innerException) { }
}
public partial class TransactionInDoubtException : System.Transactions.TransactionException
{
public TransactionInDoubtException() { }
protected TransactionInDoubtException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public TransactionInDoubtException(string message) { }
- public TransactionInDoubtException(string message, System.Exception innerException) { }
+ public TransactionInDoubtException(string? message) { }
+ public TransactionInDoubtException(string? message, System.Exception? innerException) { }
}
public partial class TransactionInformation
{
public static partial class TransactionManager
{
public static System.TimeSpan DefaultTimeout { get { throw null; } }
- public static System.Transactions.HostCurrentTransactionCallback HostCurrentCallback { get { throw null; } set { } }
+ [System.Diagnostics.CodeAnalysis.DisallowNullAttribute]
+ public static System.Transactions.HostCurrentTransactionCallback? HostCurrentCallback { get { throw null; } set { } }
public static System.TimeSpan MaximumTimeout { get { throw null; } }
- public static event System.Transactions.TransactionStartedEventHandler DistributedTransactionStarted { add { } remove { } }
+ 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; }
}
{
public TransactionManagerCommunicationException() { }
protected TransactionManagerCommunicationException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public TransactionManagerCommunicationException(string message) { }
- public TransactionManagerCommunicationException(string message, System.Exception innerException) { }
+ public TransactionManagerCommunicationException(string? message) { }
+ public TransactionManagerCommunicationException(string? message, System.Exception? innerException) { }
}
public partial struct TransactionOptions
{
private int _dummyPrimitive;
public System.Transactions.IsolationLevel IsolationLevel { get { throw null; } set { } }
public System.TimeSpan Timeout { get { throw null; } set { } }
- public override bool Equals(object obj) { throw null; }
+ public override bool Equals(object? obj) { throw null; }
public override int GetHashCode() { throw null; }
public static bool operator ==(System.Transactions.TransactionOptions x, System.Transactions.TransactionOptions y) { throw null; }
public static bool operator !=(System.Transactions.TransactionOptions x, System.Transactions.TransactionOptions y) { throw null; }
{
public TransactionPromotionException() { }
protected TransactionPromotionException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public TransactionPromotionException(string message) { }
- public TransactionPromotionException(string message, System.Exception innerException) { }
+ public TransactionPromotionException(string? message) { }
+ public TransactionPromotionException(string? message, System.Exception? innerException) { }
}
public sealed partial class TransactionScope : System.IDisposable
{
RequiresNew = 1,
Suppress = 2,
}
- public delegate void TransactionStartedEventHandler(object sender, System.Transactions.TransactionEventArgs e);
+ public delegate void TransactionStartedEventHandler(object? sender, System.Transactions.TransactionEventArgs e);
public enum TransactionStatus
{
Active = 0,
<PropertyGroup>
<OutputType>Library</OutputType>
<Configurations>netcoreapp-Debug;netcoreapp-Release</Configurations>
+ <Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Include="System.Transactions.Local.cs" />
<IsPartialFacadeAssembly>true</IsPartialFacadeAssembly>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Configurations>netcoreapp-Debug;netcoreapp-Release</Configurations>
+ <Nullable>enable</Nullable>
</PropertyGroup>
<!-- Default configurations to help VS understand the options -->
<ItemGroup>
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Diagnostics;
using System.Threading;
namespace System.Transactions
{
}
- internal CommittableTransaction(IsolationLevel isoLevel, TimeSpan timeout) : base(isoLevel, (InternalTransaction)null)
+ internal CommittableTransaction(IsolationLevel isoLevel, TimeSpan timeout) : base(isoLevel, (InternalTransaction?)null)
{
// object to use for synchronization rather than locking on a public object
_internalTransaction = new InternalTransaction(timeout, this);
}
}
- public IAsyncResult BeginCommit(AsyncCallback asyncCallback, object asyncState)
+ public IAsyncResult BeginCommit(AsyncCallback? asyncCallback, object? asyncState)
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
throw TransactionException.CreateTransactionCompletedException(DistributedTxId);
}
+ Debug.Assert(_internalTransaction.State != null);
// this.complete will get set to true when the transaction enters a state that is
// beyond Phase0.
_internalTransaction.State.BeginCommit(_internalTransaction, true, asyncCallback, asyncState);
throw TransactionException.CreateTransactionCompletedException(DistributedTxId);
}
+ Debug.Assert(_internalTransaction.State != null);
_internalTransaction.State.BeginCommit(_internalTransaction, false, null, null);
// now that commit has started wait for the monitor on the transaction to know
return;
}
+ Debug.Assert(_internalTransaction.State != null);
if (_internalTransaction.State.get_Status(_internalTransaction) == TransactionStatus.Active)
{
lock (_internalTransaction)
{
do
{
+ Debug.Assert(_internalTransaction.State != null);
if (_internalTransaction.State.IsCompleted(_internalTransaction))
{
break;
}
}
- object IAsyncResult.AsyncState => _internalTransaction._asyncState;
+ object? IAsyncResult.AsyncState => _internalTransaction._asyncState;
bool IAsyncResult.CompletedSynchronously => _completedSynchronously;
{
if (_internalTransaction._asyncResultEvent == null)
{
+ Debug.Assert(_internalTransaction.State != null);
// Demand create an event that is already signaled if the transaction has completed.
ManualResetEvent temp = new ManualResetEvent(
_internalTransaction.State.get_Status(_internalTransaction) != TransactionStatus.Active);
{
lock (_internalTransaction)
{
+ Debug.Assert(_internalTransaction.State != null);
return _internalTransaction.State.get_Status(_internalTransaction) != TransactionStatus.Active;
}
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Diagnostics;
namespace System.Transactions
{
_blocking = blocking;
lock (_internalTransaction)
{
+ Debug.Assert(_internalTransaction.State != null);
if (blocking)
{
_internalTransaction.State.CreateBlockingClone(_internalTransaction);
_complete = true;
+ Debug.Assert(_internalTransaction.State != null);
if (_blocking)
{
_internalTransaction.State.CompleteBlockingClone(_internalTransaction);
{
internal sealed class DistributedTransactionManager
{
- internal object NodeName { get; set; }
+ internal object? NodeName { get; set; }
internal IPromotedEnlistment ReenlistTransaction(Guid resourceManagerIdentifier, byte[] resourceManagerRecoveryInformation, RecoveringInternalEnlistment internalEnlistment)
{
throw new PlatformNotSupportedException();
}
- internal Exception InnerException { get; set; }
+ internal Exception? InnerException { get; set; }
internal Guid Identifier { get; set; }
- internal RealDistributedTransaction RealTransaction { get; set; }
+ internal RealDistributedTransaction? RealTransaction { get; set; }
internal TransactionTraceIdentifier TransactionTraceId { get; set; }
internal IsolationLevel IsolationLevel { get; set; }
- internal Transaction SavedLtmPromotedTransaction { get; set; }
+ internal Transaction? SavedLtmPromotedTransaction { get; set; }
internal void Dispose()
{
internal class RealDistributedTransaction
{
- internal InternalTransaction InternalTransaction { get; set; }
+ internal InternalTransaction? InternalTransaction { get; set; }
}
}
// Base class for all durable enlistment states
internal abstract class DurableEnlistmentState : EnlistmentState
{
- private static DurableEnlistmentActive s_durableEnlistmentActive;
- private static DurableEnlistmentAborting s_durableEnlistmentAborting;
- private static DurableEnlistmentCommitting s_durableEnlistmentCommitting;
- private static DurableEnlistmentDelegated s_durableEnlistmentDelegated;
- private static DurableEnlistmentEnded s_durableEnlistmentEnded;
+ private static DurableEnlistmentActive? s_durableEnlistmentActive;
+ private static DurableEnlistmentAborting? s_durableEnlistmentAborting;
+ private static DurableEnlistmentCommitting? s_durableEnlistmentCommitting;
+ private static DurableEnlistmentDelegated? s_durableEnlistmentDelegated;
+ private static DurableEnlistmentEnded? s_durableEnlistmentEnded;
// Object for synchronizing access to the entire class( avoiding lock( typeof( ... )) )
- private static object s_classSyncObject;
+ private static object? s_classSyncObject;
internal static DurableEnlistmentActive DurableEnlistmentActive =>
LazyInitializer.EnsureInitialized(ref s_durableEnlistmentActive, ref s_classSyncObject, () => new DurableEnlistmentActive());
}
}
- internal override void Aborted(InternalEnlistment enlistment, Exception e)
+ internal override void Aborted(InternalEnlistment enlistment, Exception? e)
{
if (enlistment.Transaction._innerException == null)
{
// Transition to the ended state
DurableEnlistmentEnded.EnterState(enlistment);
+ Debug.Assert(enlistment.Transaction.State != null);
// Make the transaction commit
enlistment.Transaction.State.ChangeStateTransactionCommitted(enlistment.Transaction);
}
// Transition to the ended state
DurableEnlistmentEnded.EnterState(enlistment);
+ Debug.Assert(enlistment.Transaction.State != null);
// Make the transaction commit
enlistment.Transaction.State.ChangeStateTransactionCommitted(enlistment.Transaction);
}
- internal override void Aborted(InternalEnlistment enlistment, Exception e)
+ internal override void Aborted(InternalEnlistment enlistment, Exception? e)
{
// Transition to the ended state
DurableEnlistmentEnded.EnterState(enlistment);
+ Debug.Assert(enlistment.Transaction.State != null);
// Start the transaction aborting
enlistment.Transaction.State.ChangeStateTransactionAborted(enlistment.Transaction, e);
}
- internal override void InDoubt(InternalEnlistment enlistment, Exception e)
+ internal override void InDoubt(InternalEnlistment enlistment, Exception? e)
{
// Transition to the ended state
DurableEnlistmentEnded.EnterState(enlistment);
enlistment.Transaction._innerException = e;
}
+ Debug.Assert(enlistment.Transaction.State != null);
// Make the transaction in dobut
enlistment.Transaction.State.InDoubtFromEnlistment(enlistment.Transaction);
}
// Transition to the ended state
DurableEnlistmentEnded.EnterState(enlistment);
+ Debug.Assert(enlistment.Transaction.State != null);
// Change the transaction to committed.
enlistment.Transaction.State.ChangeStatePromotedCommitted(enlistment.Transaction);
}
- internal override void Aborted(InternalEnlistment enlistment, Exception e)
+ internal override void Aborted(InternalEnlistment enlistment, Exception? e)
{
// Transition to the ended state
DurableEnlistmentEnded.EnterState(enlistment);
enlistment.Transaction._innerException = e;
}
+ Debug.Assert(enlistment.Transaction.State != null);
// Start the transaction aborting
enlistment.Transaction.State.ChangeStatePromotedAborted(enlistment.Transaction);
}
- internal override void InDoubt(InternalEnlistment enlistment, Exception e)
+ internal override void InDoubt(InternalEnlistment enlistment, Exception? e)
{
// Transition to the ended state
DurableEnlistmentEnded.EnterState(enlistment);
enlistment.Transaction._innerException = e;
}
+ Debug.Assert(enlistment.Transaction.State != null);
// Tell the transaction that the enlistment is InDoubt. Note that
// for a transaction that has been delegated and then promoted there
// are two chances to get a better answer than indoubt. So it may be that
// it already knows. Eat this message.
}
- internal override void InDoubt(InternalEnlistment enlistment, Exception e)
+ internal override void InDoubt(InternalEnlistment enlistment, Exception? e)
{
// Ignore this in case the enlistment gets here before
// the transaction tells it to do so
void ForceRollback();
- void ForceRollback(Exception e);
+ void ForceRollback(Exception? e);
void Committed();
void Aborted();
- void Aborted(Exception e);
+ void Aborted(Exception? e);
void InDoubt();
- void InDoubt(Exception e);
+ void InDoubt(Exception? e);
byte[] GetRecoveryInformation();
internal class InternalEnlistment : ISinglePhaseNotificationInternal
{
// Storage for the state of the enlistment.
- internal EnlistmentState _twoPhaseState;
+ internal EnlistmentState? _twoPhaseState;
// Interface implemented by the enlistment owner for notifications
- protected IEnlistmentNotification _twoPhaseNotifications;
+ protected IEnlistmentNotification? _twoPhaseNotifications;
// Store a reference to the single phase notification interface in case
// the enlisment supports it.
- protected ISinglePhaseNotification _singlePhaseNotifications;
+ protected ISinglePhaseNotification? _singlePhaseNotifications;
// Reference to the containing transaction.
- protected InternalTransaction _transaction;
+ protected InternalTransaction _transaction = null!;
// Reference to the lightweight transaction.
- private readonly Transaction _atomicTransaction;
+ private readonly Transaction? _atomicTransaction;
// The EnlistmentTraceIdentifier for this enlistment.
private EnlistmentTraceIdentifier _traceIdentifier;
// Parent Enlistment Object
private readonly Enlistment _enlistment;
- private PreparingEnlistment _preparingEnlistment;
- private SinglePhaseEnlistment _singlePhaseEnlistment;
+ private PreparingEnlistment? _preparingEnlistment;
+ private SinglePhaseEnlistment? _singlePhaseEnlistment;
// If this enlistment is promoted store the object it delegates to.
- private IPromotedEnlistment _promotedEnlistment;
+ private IPromotedEnlistment? _promotedEnlistment;
// For Recovering Enlistments
protected InternalEnlistment(Enlistment enlistment, IEnlistmentNotification twoPhaseNotifications)
Enlistment enlistment,
InternalTransaction transaction,
IEnlistmentNotification twoPhaseNotifications,
- ISinglePhaseNotification singlePhaseNotifications,
+ ISinglePhaseNotification? singlePhaseNotifications,
Transaction atomicTransaction)
{
_enlistment = enlistment;
internal EnlistmentState State
{
- get { return _twoPhaseState; }
+ get {
+ Debug.Assert(_twoPhaseState != null);
+ return _twoPhaseState;
+ }
set { _twoPhaseState = value; }
}
}
}
- internal IEnlistmentNotification EnlistmentNotification => _twoPhaseNotifications;
+ internal IEnlistmentNotification? EnlistmentNotification => _twoPhaseNotifications;
- internal ISinglePhaseNotification SinglePhaseNotification => _singlePhaseNotifications;
+ internal ISinglePhaseNotification? SinglePhaseNotification => _singlePhaseNotifications;
internal virtual IPromotableSinglePhaseNotification PromotableSinglePhaseNotification
{
}
}
- internal IPromotedEnlistment PromotedEnlistment
+ internal IPromotedEnlistment? PromotedEnlistment
{
get { return _promotedEnlistment; }
set { _promotedEnlistment = value; }
if (Transaction._phase0Volatiles._preparedVolatileEnlistments ==
Transaction._phase0VolatileWaveCount + Transaction._phase0Volatiles._dependentClones)
{
- Transaction.State.Phase0VolatilePrepareDone(Transaction);
+ Transaction.State!.Phase0VolatilePrepareDone(Transaction);
}
}
_promotedEnlistment = singlePhaseEnlistment;
try
{
+ Debug.Assert(_singlePhaseNotifications != null);
_singlePhaseNotifications.SinglePhaseCommit(SinglePhaseEnlistment);
spcCommitted = true;
}
IPromotedEnlistment preparingEnlistment
)
{
+ Debug.Assert(_twoPhaseNotifications != null);
_promotedEnlistment = preparingEnlistment;
_twoPhaseNotifications.Prepare(PreparingEnlistment);
}
IPromotedEnlistment enlistment
)
{
+ Debug.Assert(_twoPhaseNotifications != null);
_promotedEnlistment = enlistment;
_twoPhaseNotifications.Commit(Enlistment);
}
IPromotedEnlistment enlistment
)
{
+ Debug.Assert(_twoPhaseNotifications != null);
_promotedEnlistment = enlistment;
_twoPhaseNotifications.Rollback(Enlistment);
}
IPromotedEnlistment enlistment
)
{
+ Debug.Assert(_twoPhaseNotifications != null);
_promotedEnlistment = enlistment;
_twoPhaseNotifications.InDoubt(Enlistment);
}
Guid resourceManagerIdentifier,
InternalTransaction transaction,
IEnlistmentNotification twoPhaseNotifications,
- ISinglePhaseNotification singlePhaseNotifications,
+ ISinglePhaseNotification? singlePhaseNotifications,
Transaction atomicTransaction) :
base(enlistment, transaction, twoPhaseNotifications, singlePhaseNotifications, atomicTransaction)
{
Enlistment enlistment,
InternalTransaction transaction,
IEnlistmentNotification twoPhaseNotifications,
- ISinglePhaseNotification singlePhaseNotifications,
+ ISinglePhaseNotification? singlePhaseNotifications,
Transaction atomicTransaction)
: base(enlistment, transaction, twoPhaseNotifications, singlePhaseNotifications, atomicTransaction)
{
_transaction._phase1Volatiles._volatileEnlistmentCount +
_transaction._phase1Volatiles._dependentClones)
{
- _transaction.State.Phase1VolatilePrepareDone(_transaction);
+ _transaction.State!.Phase1VolatilePrepareDone(_transaction);
}
}
}
Guid resourceManagerIdentifier,
InternalTransaction transaction,
IEnlistmentNotification twoPhaseNotifications,
- ISinglePhaseNotification singlePhaseNotifications,
+ ISinglePhaseNotification? singlePhaseNotifications,
Transaction atomicTransaction)
{
_internalEnlistment = new DurableInternalEnlistment(
internal Enlistment(
InternalTransaction transaction,
IEnlistmentNotification twoPhaseNotifications,
- ISinglePhaseNotification singlePhaseNotifications,
+ ISinglePhaseNotification? singlePhaseNotifications,
Transaction atomicTransaction,
EnlistmentOptions enlistmentOptions)
{
{
internal abstract void EnterState(InternalEnlistment enlistment);
- internal static EnlistmentStatePromoted _enlistmentStatePromoted;
+ internal static EnlistmentStatePromoted? _enlistmentStatePromoted;
// Object for synchronizing access to the entire class( avoiding lock( typeof( ... )) )
- private static object s_classSyncObject;
+ private static object? s_classSyncObject;
internal static EnlistmentStatePromoted EnlistmentStatePromoted =>
LazyInitializer.EnsureInitialized(ref _enlistmentStatePromoted, ref s_classSyncObject, () => new EnlistmentStatePromoted());
throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId);
}
- internal virtual void ForceRollback(InternalEnlistment enlistment, Exception e)
+ internal virtual void ForceRollback(InternalEnlistment enlistment, Exception? e)
{
throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId);
}
throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId);
}
- internal virtual void Aborted(InternalEnlistment enlistment, Exception e)
+ internal virtual void Aborted(InternalEnlistment enlistment, Exception? e)
{
throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId);
}
- internal virtual void InDoubt(InternalEnlistment enlistment, Exception e)
+ internal virtual void InDoubt(InternalEnlistment enlistment, Exception? e)
{
throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId);
}
Monitor.Exit(enlistment.SyncRoot);
try
{
+ Debug.Assert(enlistment.PromotedEnlistment != null);
enlistment.PromotedEnlistment.EnlistmentDone();
}
finally
Monitor.Exit(enlistment.SyncRoot);
try
{
+ Debug.Assert(enlistment.PromotedEnlistment != null);
enlistment.PromotedEnlistment.Prepared();
}
finally
}
}
- internal override void ForceRollback(InternalEnlistment enlistment, Exception e)
+ internal override void ForceRollback(InternalEnlistment enlistment, Exception? e)
{
Monitor.Exit(enlistment.SyncRoot);
try
{
+ Debug.Assert(enlistment.PromotedEnlistment != null);
enlistment.PromotedEnlistment.ForceRollback(e);
}
finally
Monitor.Exit(enlistment.SyncRoot);
try
{
+ Debug.Assert(enlistment.PromotedEnlistment != null);
enlistment.PromotedEnlistment.Committed();
}
finally
}
}
- internal override void Aborted(InternalEnlistment enlistment, Exception e)
+ internal override void Aborted(InternalEnlistment enlistment, Exception? e)
{
Monitor.Exit(enlistment.SyncRoot);
try
{
+ Debug.Assert(enlistment.PromotedEnlistment != null);
enlistment.PromotedEnlistment.Aborted(e);
}
finally
}
}
- internal override void InDoubt(InternalEnlistment enlistment, Exception e)
+ internal override void InDoubt(InternalEnlistment enlistment, Exception? e)
{
Monitor.Exit(enlistment.SyncRoot);
try
{
+ Debug.Assert(enlistment.PromotedEnlistment != null);
enlistment.PromotedEnlistment.InDoubt(e);
}
finally
Monitor.Exit(enlistment.SyncRoot);
try
{
+ Debug.Assert(enlistment.PromotedEnlistment != null);
return enlistment.PromotedEnlistment.GetRecoveryInformation();
}
finally
public override int GetHashCode() => base.GetHashCode(); // Don't have anything better to do.
- public override bool Equals(object obj) => obj is EnlistmentTraceIdentifier && Equals((EnlistmentTraceIdentifier)obj);
+ public override bool Equals(object? obj) => obj is EnlistmentTraceIdentifier enlistmentTraceId && Equals(enlistmentTraceId);
public bool Equals(EnlistmentTraceIdentifier other) =>
_enlistmentIdentifier == other._enlistmentIdentifier &&
}
}
- internal static Transaction GetContextTransaction(ContextData contextData)
+ internal static Transaction? GetContextTransaction(ContextData contextData)
{
if (EnterpriseServicesOk)
{
internal static bool UseServiceDomainForCurrent() => false;
- internal static void PushServiceDomain(Transaction newCurrent)
+ internal static void PushServiceDomain(Transaction? newCurrent)
{
ThrowNotSupported();
}
{
public interface ITransactionPromoter
{
- byte[] Promote();
+ byte[]? Promote();
}
}
{
// This variable manages the state of the transaction it should be one of the
// static elements of TransactionState derived from TransactionState.
- protected TransactionState _transactionState;
+ protected TransactionState? _transactionState;
- internal TransactionState State
+ internal TransactionState? State
{
get { return _transactionState; }
set { _transactionState = value; }
// The promoted token for the transaction.
// This is set when the transaction is promoted. For an MSDTC transaction, it is the
// same as the DTC propagation token.
- internal byte[] promotedToken;
+ internal byte[]? promotedToken;
// This is only used if the promoter type is different than TransactionInterop.PromoterTypeDtc.
// The promoter is supposed to tell us what the distributed transaction id after promoting it.
#endif
// Finalized object see class definition for the use of this object
- internal FinalizedObject _finalizedObject;
+ internal FinalizedObject? _finalizedObject;
internal readonly int _transactionHash;
internal int TransactionHash => _transactionHash;
// operation repeatedly for a given type of transaction. So if a transaction of a specific
// type continually causes the array size to be increased the LTM could start
// allocating a larger array initially for transactions of that type.
- internal InternalEnlistment _durableEnlistment;
+ internal InternalEnlistment? _durableEnlistment;
internal VolatileEnlistmentSet _phase0Volatiles;
internal VolatileEnlistmentSet _phase1Volatiles;
// These members are used for promoted waves of dependent blocking clones. The Ltm
// does not register individually for each blocking clone created in phase 0. Instead
// it multiplexes a single phase 0 blocking clone only created after phase 0 has started.
- internal DistributedDependentTransaction _phase0WaveDependentClone;
+ internal DistributedDependentTransaction? _phase0WaveDependentClone;
internal int _phase0WaveDependentCloneCount;
// These members are used for keeping track of aborting dependent clones if we promote
// on the distributed TM takes care of checking to make sure all the aborting dependent
// clones have completed as part of its Prepare processing. These are used in conjunction with
// phase1volatiles.dependentclones.
- internal DistributedDependentTransaction _abortingDependentClone;
+ internal DistributedDependentTransaction? _abortingDependentClone;
internal int _abortingDependentCloneCount;
// When the size of the volatile enlistment array grows increase it by this amount.
internal const int VolatileArrayIncrement = 8;
// Data maintained for TransactionTable participation
- internal Bucket _tableBucket;
+ internal Bucket? _tableBucket;
internal int _bucketIndex;
// Delegate to fire on transaction completion
- internal TransactionCompletedEventHandler _transactionCompletedDelegate;
+ internal TransactionCompletedEventHandler? _transactionCompletedDelegate;
// If this transaction get's promoted keep a reference to the promoted transaction
- private DistributedTransaction _promotedTransaction;
- internal DistributedTransaction PromotedTransaction
+ private DistributedTransaction? _promotedTransaction;
+ internal DistributedTransaction? PromotedTransaction
{
get { return _promotedTransaction; }
set
// If there was an exception that happened during promotion save that exception so that it
// can be used as an inner exception to the transaciton aborted exception.
- internal Exception _innerException = null;
+ internal Exception? _innerException = null;
// Note the number of Transaction objects supported by this object
internal int _cloneCount;
// Double-checked locking pattern requires volatile for read/write synchronization
// Manual Reset event for IAsyncResult support
- internal volatile ManualResetEvent _asyncResultEvent;
+ internal volatile ManualResetEvent? _asyncResultEvent;
// Store the callback and state for the caller of BeginCommit
internal bool _asyncCommit;
- internal AsyncCallback _asyncCallback;
- internal object _asyncState;
+ internal AsyncCallback? _asyncCallback;
+ internal object? _asyncState;
// Flag to indicate if we need to be pulsed for tx completion
internal bool _needPulse;
// Store the transaction information object
- internal TransactionInformation _transactionInformation;
+ internal TransactionInformation? _transactionInformation;
// Store a reference to the owning Committable Transaction
- internal readonly CommittableTransaction _committableTransaction;
+ internal readonly CommittableTransaction? _committableTransaction;
// Store a reference to the outcome source
internal readonly Transaction _outcomeSource;
// Object for synchronizing access to the entire class( avoiding lock( typeof( ... )) )
- private static object s_classSyncObject;
+ private static object? s_classSyncObject;
- internal Guid DistributedTxId => State.get_Identifier(this);
+ internal Guid DistributedTxId => State!.get_Identifier(this);
- private static string s_instanceIdentifier;
+ private static string? s_instanceIdentifier;
internal static string InstanceIdentifier =>
LazyInitializer.EnsureInitialized(ref s_instanceIdentifier, ref s_classSyncObject, () => Guid.NewGuid().ToString() + ":");
}
}
- internal ITransactionPromoter _promoter;
+ internal ITransactionPromoter? _promoter;
// This member is used to allow a PSPE enlistment to call Transaction.PSPEPromoteAndConvertToEnlistDurable when it is
// asked to promote a transaction. The value is set to true in TransactionStatePSPEOperation.PSPEPromote before the
internal static void DistributedTransactionOutcome(InternalTransaction tx, TransactionStatus status)
{
- FinalizedObject fo = null;
+ FinalizedObject? fo = null;
lock (tx)
{
if (null == tx._innerException)
{
+ Debug.Assert(tx.PromotedTransaction != null);
tx._innerException = tx.PromotedTransaction.InnerException;
}
+ Debug.Assert(tx.State! != null);
switch (status)
{
case TransactionStatus.Committed:
Monitor.Exit(this); // Don't hold a lock calling user code.
try
{
+ Debug.Assert(_committableTransaction != null);
_asyncCallback(_committableTransaction);
}
finally
// Fire completion to anyone registered for outcome
internal void FireCompletion()
{
- TransactionCompletedEventHandler eventHandlers = _transactionCompletedDelegate;
+ TransactionCompletedEventHandler? eventHandlers = _transactionCompletedDelegate;
if (eventHandlers != null)
{
Hashtable promotedTransactionTable = TransactionManager.PromotedTransactionTable;
lock (promotedTransactionTable)
{
- WeakReference weakRef = (WeakReference)promotedTransactionTable[_identifier];
+ WeakReference? weakRef = (WeakReference?)promotedTransactionTable[_identifier];
if (null != weakRef)
{
if (weakRef.Target != null)
}
}
- public void ForceRollback(Exception e)
+ public void ForceRollback(Exception? e)
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
}
}
- public void Aborted(Exception e)
+ public void Aborted(Exception? e)
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
}
- public void InDoubt(Exception e)
+ public void InDoubt(Exception? e)
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Threading;
{
public class TransactionEventArgs : EventArgs
{
- internal Transaction _transaction;
- public Transaction Transaction => _transaction;
+ internal Transaction? _transaction;
+ public Transaction? Transaction => _transaction;
}
- public delegate void TransactionCompletedEventHandler(object sender, TransactionEventArgs e);
+ public delegate void TransactionCompletedEventHandler(object? sender, TransactionEventArgs e);
public enum IsolationLevel
{
// This property figures out the current interop mode based on the
// top of the transaction scope stack as well as the default mode
// from config.
- internal static EnterpriseServicesInteropOption InteropMode(TransactionScope currentScope)
+ internal static EnterpriseServicesInteropOption InteropMode(TransactionScope? currentScope)
{
if (currentScope != null)
{
return EnterpriseServicesInteropOption.None;
}
- internal static Transaction FastGetTransaction(TransactionScope currentScope, ContextData contextData, out Transaction contextTransaction)
+ internal static Transaction? FastGetTransaction(TransactionScope? currentScope, ContextData contextData, out Transaction? contextTransaction)
{
- Transaction current = null;
+ Transaction? current = null;
contextTransaction = null;
contextTransaction = contextData.CurrentTransaction;
// Otherwise check for an external current.
if (TransactionManager.s_currentDelegateSet)
{
- current = TransactionManager.s_currentDelegate();
+ current = TransactionManager.s_currentDelegate!();
}
else
{
// in TransactionScope because it is required to get both of them in several cases.
internal static void GetCurrentTransactionAndScope(
TxLookup defaultLookup,
- out Transaction current,
- out TransactionScope currentScope,
- out Transaction contextTransaction)
+ out Transaction? current,
+ out TransactionScope? currentScope,
+ out Transaction? contextTransaction)
{
current = null;
currentScope = null;
}
}
- public static Transaction Current
+ public static Transaction? Current
{
get
{
etwLog.MethodEnter(TraceSourceType.TraceSourceBase, "Transaction.get_Current");
}
- Transaction current = null;
- TransactionScope currentScope = null;
- Transaction contextValue = null;
- GetCurrentTransactionAndScope(TxLookup.Default, out current, out currentScope, out contextValue);
+ GetCurrentTransactionAndScope(TxLookup.Default, out Transaction? current, out TransactionScope? currentScope, out Transaction? contextValue);
if (currentScope != null)
{
// Internal synchronization object for transactions. It is not safe to lock on the
// transaction object because it is public and users of the object may lock it for
// other purposes.
- internal InternalTransaction _internalTransaction;
+ internal InternalTransaction _internalTransaction = null!;
// The TransactionTraceIdentifier for the transaction instance.
internal TransactionTraceIdentifier _traceIdentifier;
// Create a transaction with the given settings
//
- internal Transaction(IsolationLevel isoLevel, InternalTransaction internalTransaction)
+ internal Transaction(IsolationLevel isoLevel, InternalTransaction? internalTransaction)
{
TransactionManager.ValidateIsolationLevel(isoLevel);
// Don't allow equals to get the identifier
//
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
- Transaction transaction = obj as Transaction;
-
// If we can't cast the object as a Transaction, it must not be equal
- // to this, which is a Transaction.
- if (null == transaction)
- {
- return false;
- }
-
- // Check the internal transaction object for equality.
- return _internalTransaction.TransactionHash == transaction._internalTransaction.TransactionHash;
+ // to this, which is a Transaction. Check the internal transaction object for equality.
+ return obj is Transaction transaction && _internalTransaction.TransactionHash == transaction._internalTransaction.TransactionHash;
}
- public static bool operator ==(Transaction x, Transaction y)
+ public static bool operator ==(Transaction? x, Transaction? y)
{
- if (((object)x) != null)
+ if (((object?)x) != null)
{
return x.Equals(y);
}
- return ((object)y) == null;
+ return ((object?)y) == null;
}
- public static bool operator !=(Transaction x, Transaction y)
+ public static bool operator !=(Transaction? x, Transaction? y)
{
- if (((object)x) != null)
+ if (((object?)x) != null)
{
return !x.Equals(y);
}
- return ((object)y) != null;
+ return ((object?)y) != null;
}
throw new ObjectDisposedException(nameof(Transaction));
}
- TransactionInformation txInfo = _internalTransaction._transactionInformation;
+ TransactionInformation? txInfo = _internalTransaction._transactionInformation;
if (txInfo == null)
{
// A race would only result in an extra allocation
byte[] internalPromotedToken;
lock (_internalTransaction)
{
+ Debug.Assert(_internalTransaction.State != null);
internalPromotedToken = _internalTransaction.State.PromotedToken(_internalTransaction);
}
lock (_internalTransaction)
{
+ Debug.Assert(_internalTransaction.State != null);
Enlistment enlistment = _internalTransaction.State.EnlistDurable(_internalTransaction,
resourceManagerIdentifier, enlistmentNotification, enlistmentOptions, this);
lock (_internalTransaction)
{
+ Debug.Assert(_internalTransaction.State != null);
Enlistment enlistment = _internalTransaction.State.EnlistDurable(_internalTransaction,
resourceManagerIdentifier, singlePhaseNotification, enlistmentOptions, this);
}
- public void Rollback(Exception e)
+ public void Rollback(Exception? e)
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
lock (_internalTransaction)
{
+ Debug.Assert(_internalTransaction.State != null);
Enlistment enlistment = _internalTransaction.State.EnlistVolatile(_internalTransaction,
enlistmentNotification, enlistmentOptions, this);
lock (_internalTransaction)
{
+ Debug.Assert(_internalTransaction.State != null);
Enlistment enlistment = _internalTransaction.State.EnlistVolatile(_internalTransaction,
singlePhaseNotification, enlistmentOptions, this);
// Forward request to the state machine to take the appropriate action.
//
- public event TransactionCompletedEventHandler TransactionCompleted
+ public event TransactionCompletedEventHandler? TransactionCompleted
{
add
{
lock (_internalTransaction)
{
+ Debug.Assert(_internalTransaction.State != null);
// Register for completion with the inner transaction
_internalTransaction.State.AddOutcomeRegistrant(_internalTransaction, value);
}
{
lock (_internalTransaction)
{
- _internalTransaction._transactionCompletedDelegate = (TransactionCompletedEventHandler)
+ _internalTransaction._transactionCompletedDelegate = (TransactionCompletedEventHandler?)
System.Delegate.Remove(_internalTransaction._transactionCompletedDelegate, value);
}
}
lock (_internalTransaction)
{
+ Debug.Assert(_internalTransaction.State != null);
succeeded = _internalTransaction.State.EnlistPromotableSinglePhase(_internalTransaction, promotableSinglePhaseNotification, this, promoterType);
}
lock (_internalTransaction)
{
+ Debug.Assert(_internalTransaction.State != null);
Enlistment enlistment = _internalTransaction.State.PromoteAndEnlistDurable(_internalTransaction,
resourceManagerIdentifier, promotableNotification, enlistmentNotification, enlistmentOptions, this);
lock (_internalTransaction)
{
+ Debug.Assert(_internalTransaction.State != null);
_internalTransaction.State.SetDistributedTransactionId(_internalTransaction,
promotableNotification,
distributedTransactionIdentifier);
}
}
- internal DistributedTransaction Promote()
+ internal DistributedTransaction? Promote()
{
lock (_internalTransaction)
{
+ Debug.Assert(_internalTransaction.State != null);
// This method is only called when we expect to be promoting to MSDTC.
_internalTransaction.ThrowIfPromoterTypeIsNotMSDTC();
_internalTransaction.State.Promote(_internalTransaction);
//
internal static class CallContextCurrentData
{
- private static readonly AsyncLocal<ContextKey> s_currentTransaction = new AsyncLocal<ContextKey>();
+ private static readonly AsyncLocal<ContextKey?> s_currentTransaction = new AsyncLocal<ContextKey?>();
// ConditionalWeakTable is used to automatically remove the entries that are no longer referenced. This will help prevent leaks in async nested TransactionScope
// usage and when child nested scopes are not syncronized properly.
return s_contextDataTable.GetValue(contextKey, (env) => new ContextData(true));
}
- public static void ClearCurrentData(ContextKey contextKey, bool removeContextData)
+ public static void ClearCurrentData(ContextKey? contextKey, bool removeContextData)
{
// Get the current ambient CallContext.
- ContextKey key = s_currentTransaction.Value;
+ ContextKey? key = s_currentTransaction.Value;
if (contextKey != null || key != null)
{
// removeContextData flag is used for perf optimization to avoid removing from the table in certain nested TransactionScope usage.
if (removeContextData)
{
// if context key is passed in remove that from the contextDataTable, otherwise remove the default context key.
- s_contextDataTable.Remove(contextKey ?? key);
+ s_contextDataTable.Remove(contextKey ?? key!);
}
if (key != null)
}
}
- public static bool TryGetCurrentData(out ContextData currentData)
+ public static bool TryGetCurrentData([NotNullWhen(true)] out ContextData? currentData)
{
currentData = null;
- ContextKey contextKey = s_currentTransaction.Value;
+ ContextKey? contextKey = s_currentTransaction.Value;
if (contextKey == null)
{
return false;
internal class ContextData
{
- internal TransactionScope CurrentScope;
- internal Transaction CurrentTransaction;
+ internal TransactionScope? CurrentScope;
+ internal Transaction? CurrentTransaction;
internal DefaultComContextState DefaultComContextState;
- internal WeakReference WeakDefaultComContext;
+ internal WeakReference? WeakDefaultComContext;
internal bool _asyncFlow;
[ThreadStatic]
- private static ContextData t_staticData;
+ private static ContextData? t_staticData;
internal ContextData(bool asyncFlow)
{
_asyncFlow = asyncFlow;
}
+ [AllowNull]
internal static ContextData TLSCurrentData
{
get
{
- ContextData data = t_staticData;
+ ContextData? data = t_staticData;
if (data == null)
{
data = new ContextData(false);
internal static ContextData LookupContextData(TxLookup defaultLookup)
{
- ContextData currentData = null;
+ ContextData? currentData = null;
if (CallContextCurrentData.TryGetCurrentData(out currentData))
{
if (currentData.CurrentScope == null && currentData.CurrentTransaction == null && defaultLookup != TxLookup.DefaultCallContext)
return (distributedTxId != Guid.Empty && AppSettings.IncludeDistributedTxIdInExceptionMessage);
}
- internal static TransactionException Create(string message, Exception innerException)
+ internal static TransactionException Create(string? message, Exception? innerException)
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
return new TransactionException(message, innerException);
}
- internal static TransactionException Create(TraceSourceType traceSource, string message, Exception innerException)
+ internal static TransactionException Create(TraceSourceType traceSource, string? message, Exception? innerException)
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
return new TransactionException(message, innerException);
}
- internal static TransactionException CreateTransactionStateException(Exception innerException)
+ internal static TransactionException CreateTransactionStateException(Exception? innerException)
{
return Create(SR.TransactionStateException, innerException);
}
- internal static Exception CreateEnlistmentStateException(Exception innerException, Guid distributedTxId)
+ internal static Exception CreateEnlistmentStateException(Exception? innerException, Guid distributedTxId)
{
string messagewithTxId = SR.EnlistmentStateException;
if (IncludeDistributedTxId(distributedTxId))
return new InvalidOperationException(messagewithTxId, innerException);
}
- internal static Exception CreateInvalidOperationException(TraceSourceType traceSource, string message, Exception innerException)
+ internal static Exception CreateInvalidOperationException(TraceSourceType traceSource, string? message, Exception? innerException)
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
///
/// </summary>
/// <param name="message"></param>
- public TransactionException(string message) : base(message)
+ public TransactionException(string? message) : base(message)
{
}
/// </summary>
/// <param name="message"></param>
/// <param name="innerException"></param>
- public TransactionException(string message, Exception innerException) : base(message, innerException)
+ public TransactionException(string? message, Exception? innerException) : base(message, innerException)
{
}
{
}
- internal static TransactionException Create(string message, Guid distributedTxId)
+ internal static TransactionException Create(string? message, Guid distributedTxId)
{
if (IncludeDistributedTxId(distributedTxId))
{
return new TransactionException(message);
}
- internal static TransactionException Create(string message, Exception innerException, Guid distributedTxId)
+ internal static TransactionException Create(string? message, Exception? innerException, Guid distributedTxId)
{
- string messagewithTxId = message;
+ string? messagewithTxId = message;
if (IncludeDistributedTxId(distributedTxId))
messagewithTxId = SR.Format(SR.DistributedTxIDInTransactionException, messagewithTxId, distributedTxId);
return Create(messagewithTxId, innerException);
}
- internal static TransactionException Create(TraceSourceType traceSource, string message, Exception innerException, Guid distributedTxId)
+ internal static TransactionException Create(TraceSourceType traceSource, string? message, Exception? innerException, Guid distributedTxId)
{
- string messagewithTxId = message;
+ string? messagewithTxId = message;
if (IncludeDistributedTxId(distributedTxId))
messagewithTxId = SR.Format(SR.DistributedTxIDInTransactionException, messagewithTxId, distributedTxId);
return Create(traceSource, messagewithTxId, innerException);
}
- internal static TransactionException Create(TraceSourceType traceSource, string message, Guid distributedTxId)
+ internal static TransactionException Create(TraceSourceType traceSource, string? message, Guid distributedTxId)
{
if (IncludeDistributedTxId(distributedTxId))
{
return new TransactionException(message);
}
- internal static TransactionException CreateTransactionStateException(Exception innerException, Guid distributedTxId)
+ internal static TransactionException CreateTransactionStateException(Exception? innerException, Guid distributedTxId)
{
return Create(SR.TransactionStateException, innerException, distributedTxId);
}
return new InvalidOperationException(messagewithTxId);
}
- internal static Exception CreateInvalidOperationException(TraceSourceType traceSource, string message, Exception innerException, Guid distributedTxId)
+ internal static Exception CreateInvalidOperationException(TraceSourceType traceSource, string? message, Exception? innerException, Guid distributedTxId)
{
- string messagewithTxId = message;
+ string? messagewithTxId = message;
if (IncludeDistributedTxId(distributedTxId))
messagewithTxId = SR.Format(SR.DistributedTxIDInTransactionException, messagewithTxId, distributedTxId);
[System.Runtime.CompilerServices.TypeForwardedFrom("System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public class TransactionAbortedException : TransactionException
{
- internal static new TransactionAbortedException Create(string message, Exception innerException, Guid distributedTxId)
+ internal static new TransactionAbortedException Create(string? message, Exception? innerException, Guid distributedTxId)
{
- string messagewithTxId = message;
+ string? messagewithTxId = message;
if (IncludeDistributedTxId(distributedTxId))
messagewithTxId = SR.Format(SR.DistributedTxIDInTransactionException, messagewithTxId, distributedTxId);
return TransactionAbortedException.Create(messagewithTxId, innerException);
}
- internal static new TransactionAbortedException Create(string message, Exception innerException)
+ internal static new TransactionAbortedException Create(string? message, Exception? innerException)
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
///
/// </summary>
/// <param name="message"></param>
- public TransactionAbortedException(string message) : base(message)
+ public TransactionAbortedException(string? message) : base(message)
{
}
/// </summary>
/// <param name="message"></param>
/// <param name="innerException"></param>
- public TransactionAbortedException(string message, Exception innerException) : base(message, innerException)
+ public TransactionAbortedException(string? message, Exception? innerException) : base(message, innerException)
{
}
///
/// </summary>
/// <param name="innerException"></param>
- internal TransactionAbortedException(Exception innerException) : base(SR.TransactionAborted, innerException)
+ internal TransactionAbortedException(Exception? innerException) : base(SR.TransactionAborted, innerException)
{
}
- internal TransactionAbortedException(Exception innerException, Guid distributedTxId) :
+ internal TransactionAbortedException(Exception? innerException, Guid distributedTxId) :
base(IncludeDistributedTxId(distributedTxId) ?
SR.Format(SR.DistributedTxIDInTransactionException, SR.TransactionAborted, distributedTxId)
: SR.TransactionAborted, innerException)
[System.Runtime.CompilerServices.TypeForwardedFrom("System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public class TransactionInDoubtException : TransactionException
{
- internal static new TransactionInDoubtException Create(TraceSourceType traceSource, string message, Exception innerException, Guid distributedTxId)
+ internal static new TransactionInDoubtException Create(TraceSourceType traceSource, string? message, Exception? innerException, Guid distributedTxId)
{
- string messagewithTxId = message;
+ string? messagewithTxId = message;
if (IncludeDistributedTxId(distributedTxId))
messagewithTxId = SR.Format(SR.DistributedTxIDInTransactionException, messagewithTxId, distributedTxId);
return TransactionInDoubtException.Create(traceSource, messagewithTxId, innerException);
}
- internal static new TransactionInDoubtException Create(TraceSourceType traceSource, string message, Exception innerException)
+ internal static new TransactionInDoubtException Create(TraceSourceType traceSource, string? message, Exception? innerException)
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
///
/// </summary>
/// <param name="message"></param>
- public TransactionInDoubtException(string message) : base(message)
+ public TransactionInDoubtException(string? message) : base(message)
{
}
/// </summary>
/// <param name="message"></param>
/// <param name="innerException"></param>
- public TransactionInDoubtException(string message, Exception innerException) : base(message, innerException)
+ public TransactionInDoubtException(string? message, Exception? innerException) : base(message, innerException)
{
}
[System.Runtime.CompilerServices.TypeForwardedFrom("System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public class TransactionManagerCommunicationException : TransactionException
{
- internal static new TransactionManagerCommunicationException Create(string message, Exception innerException)
+ internal static new TransactionManagerCommunicationException Create(string? message, Exception? innerException)
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
return new TransactionManagerCommunicationException(message, innerException);
}
- internal static TransactionManagerCommunicationException Create(Exception innerException)
+ internal static TransactionManagerCommunicationException Create(Exception? innerException)
{
return Create(SR.TransactionManagerCommunicationException, innerException);
}
///
/// </summary>
/// <param name="message"></param>
- public TransactionManagerCommunicationException(string message) : base(message)
+ public TransactionManagerCommunicationException(string? message) : base(message)
{
}
/// <param name="message"></param>
/// <param name="innerException"></param>
public TransactionManagerCommunicationException(
- string message,
- Exception innerException
+ string? message,
+ Exception? innerException
) : base(message, innerException)
{
}
///
/// </summary>
/// <param name="message"></param>
- public TransactionPromotionException(string message) : base(message)
+ public TransactionPromotionException(string? message) : base(message)
{
}
/// </summary>
/// <param name="message"></param>
/// <param name="innerException"></param>
- public TransactionPromotionException(string message, Exception innerException) : base(message, innerException)
+ public TransactionPromotionException(string? message, Exception? innerException) : base(message, innerException)
{
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Diagnostics;
+
namespace System.Transactions
{
public class TransactionInformation
lock (_internalTransaction)
{
+ Debug.Assert(_internalTransaction.State != null);
return _internalTransaction.State.get_Identifier(_internalTransaction);
}
}
try
{
+ Debug.Assert(_internalTransaction.State != null);
return _internalTransaction.State.get_Status(_internalTransaction);
}
finally
throw TransactionException.CreateTransactionCompletedException(transaction.DistributedTxId);
}
- DistributedTransaction distributedTx = transaction.Promote();
+ DistributedTransaction? distributedTx = transaction.Promote();
if (distributedTx == null)
{
throw DistributedTransaction.NotSupported();
// First check to see if there is a promoted LTM transaction with the same ID. If there
// is, just return that.
- Transaction transaction = TransactionManager.FindPromotedTransaction(txId);
+ Transaction? transaction = TransactionManager.FindPromotedTransaction(txId);
if (transaction != null)
{
if (etwLog.IsEnabled())
var txId = new Guid(propagationToken.AsSpan(8, 16));
// First check to see if there is a promoted LTM transaction with the same ID. If there is, just return that.
- Transaction tx = TransactionManager.FindPromotedTransaction(txId);
+ Transaction? tx = TransactionManager.FindPromotedTransaction(txId);
if (null != tx)
{
if (etwLog.IsEnabled())
// See the LICENSE file in the project root for more information.
using System.Collections;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Runtime.Serialization;
namespace System.Transactions
{
- public delegate Transaction HostCurrentTransactionCallback();
+ public delegate Transaction? HostCurrentTransactionCallback();
- public delegate void TransactionStartedEventHandler(object sender, TransactionEventArgs e);
+ public delegate void TransactionStartedEventHandler(object? sender, TransactionEventArgs e);
public static class TransactionManager
{
// Hashtable of promoted transactions, keyed by identifier guid. This is used by
// FindPromotedTransaction to support transaction equivalence when a transaction is
// serialized and then deserialized back in this app-domain.
- private static Hashtable s_promotedTransactionTable;
+ private static Hashtable? s_promotedTransactionTable;
// Sorted Table of transaction timeouts
- private static TransactionTable s_transactionTable;
+ private static TransactionTable? s_transactionTable;
- private static TransactionStartedEventHandler s_distributedTransactionStartedDelegate;
- public static event TransactionStartedEventHandler DistributedTransactionStarted
+ private static TransactionStartedEventHandler? s_distributedTransactionStartedDelegate;
+ public static event TransactionStartedEventHandler? DistributedTransactionStarted
{
add
{
lock (ClassSyncObject)
{
- s_distributedTransactionStartedDelegate = (TransactionStartedEventHandler)System.Delegate.Combine(s_distributedTransactionStartedDelegate, value);
+ s_distributedTransactionStartedDelegate = (TransactionStartedEventHandler?)System.Delegate.Combine(s_distributedTransactionStartedDelegate, value);
if (value != null)
{
ProcessExistingTransactions(value);
{
lock (ClassSyncObject)
{
- s_distributedTransactionStartedDelegate = (TransactionStartedEventHandler)System.Delegate.Remove(s_distributedTransactionStartedDelegate, value);
+ s_distributedTransactionStartedDelegate = (TransactionStartedEventHandler?)System.Delegate.Remove(s_distributedTransactionStartedDelegate, value);
}
}
}
IDictionaryEnumerator e = PromotedTransactionTable.GetEnumerator();
while (e.MoveNext())
{
- WeakReference weakRef = (WeakReference)e.Value;
- Transaction tx = (Transaction)weakRef.Target;
- if (tx != null)
+ WeakReference weakRef = (WeakReference)e.Value!;
+
+ if (weakRef.Target is Transaction tx)
{
TransactionEventArgs args = new TransactionEventArgs();
args._transaction = tx.InternalClone();
internal static void FireDistributedTransactionStarted(Transaction transaction)
{
- TransactionStartedEventHandler localStartedEventHandler = null;
+ TransactionStartedEventHandler? localStartedEventHandler = null;
lock (ClassSyncObject)
{
localStartedEventHandler = s_distributedTransactionStartedDelegate;
}
// Data storage for current delegate
- internal static HostCurrentTransactionCallback s_currentDelegate = null;
+ internal static HostCurrentTransactionCallback? s_currentDelegate = null;
internal static bool s_currentDelegateSet = false;
// CurrentDelegate
//
// Store a delegate to be used to query for an external current transaction.
- public static HostCurrentTransactionCallback HostCurrentCallback
+ [DisallowNull]
+ public static HostCurrentTransactionCallback? HostCurrentCallback
{
// get_HostCurrentCallback is used from get_CurrentTransaction, which doesn't have any permission requirements.
// We don't expose what is returned from this property in that case. But we don't want just anybody being able
// Put the recovery information into a stream.
MemoryStream stream = new MemoryStream(recoveryInformation);
int recoveryInformationVersion = 0;
- string nodeName = null;
- byte[] resourceManagerRecoveryInformation = null;
+ string? nodeName = null;
+ byte[]? resourceManagerRecoveryInformation = null;
try
{
}
- private static DistributedTransactionManager CheckTransactionManager(string nodeName)
+ private static DistributedTransactionManager CheckTransactionManager(string? nodeName)
{
DistributedTransactionManager tm = DistributedTransactionManager;
if (!((tm.NodeName == null && (nodeName == null || nodeName.Length == 0)) ||
// Object for synchronizing access to the entire class( avoiding lock( typeof( ... )) )
- private static object s_classSyncObject;
+ private static object? s_classSyncObject;
// Helper object for static synchronization
private static object ClassSyncObject => LazyInitializer.EnsureInitialized(ref s_classSyncObject);
}
- private static DefaultSettingsSection s_defaultSettings;
+ private static DefaultSettingsSection? s_defaultSettings;
private static DefaultSettingsSection DefaultSettings
{
get
}
- private static MachineSettingsSection s_machineSettings;
+ private static MachineSettingsSection? s_machineSettings;
private static MachineSettingsSection MachineSettings
{
get
// 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
// manager object with the right parameters in order to do a ReenlistTransaction call.
- internal static byte[] GetRecoveryInformation(string startupInfo, byte[] resourceManagerRecoveryInformation)
+ internal static byte[] GetRecoveryInformation(string? startupInfo, byte[] resourceManagerRecoveryInformation)
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
}
MemoryStream stream = new MemoryStream();
- byte[] returnValue = null;
+ byte[]? returnValue = null;
try
{
internal static byte[] ConvertToByteArray(object thingToConvert)
{
MemoryStream streamToWrite = new MemoryStream();
- byte[] returnValue = null;
+ byte[]? returnValue = null;
try
{
return transactionTimeout;
}
- internal static Transaction FindPromotedTransaction(Guid transactionIdentifier)
+ internal static Transaction? FindPromotedTransaction(Guid transactionIdentifier)
{
Hashtable promotedTransactionTable = PromotedTransactionTable;
- WeakReference weakRef = (WeakReference)promotedTransactionTable[transactionIdentifier];
+ WeakReference? weakRef = (WeakReference?)promotedTransactionTable[transactionIdentifier];
if (null != weakRef)
{
- Transaction tx = weakRef.Target as Transaction;
- if (null != tx)
+ if (weakRef.Target is Transaction tx)
{
return tx.InternalClone();
}
internal static Transaction FindOrCreatePromotedTransaction(Guid transactionIdentifier, DistributedTransaction dtx)
{
- Transaction tx = null;
+ Transaction? tx = null;
Hashtable promotedTransactionTable = PromotedTransactionTable;
lock (promotedTransactionTable)
{
- WeakReference weakRef = (WeakReference)promotedTransactionTable[transactionIdentifier];
+ WeakReference? weakRef = (WeakReference?)promotedTransactionTable[transactionIdentifier];
if (null != weakRef)
{
tx = weakRef.Target as Transaction;
LazyInitializer.EnsureInitialized(ref s_transactionTable, ref s_classSyncObject, () => new TransactionTable());
// Fault in a DistributedTransactionManager if one has not already been created.
- internal static DistributedTransactionManager distributedTransactionManager;
+ internal static DistributedTransactionManager? distributedTransactionManager;
internal static DistributedTransactionManager DistributedTransactionManager =>
// If the distributed transaction manager is not configured, throw an exception
LazyInitializer.EnsureInitialized(ref distributedTransactionManager, ref s_classSyncObject, () => new DistributedTransactionManager());
public override int GetHashCode() => base.GetHashCode(); // Don't have anything better to do.
- public override bool Equals(object obj) => obj is TransactionOptions && Equals((TransactionOptions)obj);
+ public override bool Equals(object? obj) => obj is TransactionOptions transactionOptions && Equals(transactionOptions);
private bool Equals(TransactionOptions other) =>
_timeout == other._timeout &&
throw new InvalidOperationException(SR.InvalidScopeThread);
}
- Exception exToThrow = null;
+ Exception? exToThrow = null;
try
{
// Single threaded from this point
_disposed = true;
+ Debug.Assert(_threadContextData != null);
// First, lets pop the "stack" of TransactionScopes and dispose each one that is above us in
// the stack, making sure they are NOT consistent before disposing them.
// Optimize the first lookup by getting both the actual current scope and actual current
// transaction at the same time.
- TransactionScope actualCurrentScope = _threadContextData.CurrentScope;
- Transaction contextTransaction = null;
- Transaction current = Transaction.FastGetTransaction(actualCurrentScope, _threadContextData, out contextTransaction);
+ TransactionScope? actualCurrentScope = _threadContextData.CurrentScope;
+ Transaction? contextTransaction = null;
+ Transaction? current = Transaction.FastGetTransaction(actualCurrentScope, _threadContextData, out contextTransaction);
if (!Equals(actualCurrentScope))
{
// Something must have gone wrong trying to clean up a bad scope
// stack previously.
// Make a best effort to abort the active transaction.
- Transaction rollbackTransaction = _committableTransaction;
+ Transaction? rollbackTransaction = _committableTransaction;
if (rollbackTransaction == null)
{
rollbackTransaction = _dependentTransaction;
current == null ? Guid.Empty : current.DistributedTxId);
}
- if (null == actualCurrentScope._expectedCurrent)
+ if (null == actualCurrentScope!._expectedCurrent)
{
if (etwLog.IsEnabled())
{
// Note: Rollback is not called on expected current because someone could conceiveably
// dispose expectedCurrent out from under the transaction scope.
//
- Transaction rollbackTransaction = _committableTransaction;
+ Transaction? rollbackTransaction = _committableTransaction;
if (rollbackTransaction == null)
{
rollbackTransaction = _dependentTransaction;
{
_committableTransaction.Dispose();
+ Debug.Assert(_expectedCurrent != null);
// If we created the committable transaction then we placed a clone in expectedCurrent
// and it needs to be disposed as well.
_expectedCurrent.Dispose();
}
}
- private static void TimerCallback(object state)
+ private static void TimerCallback(object? state)
{
- TransactionScope scope = state as TransactionScope;
+ TransactionScope? scope = state as TransactionScope;
if (null == scope)
{
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (AsyncFlowEnabled)
{
+ Debug.Assert(ContextKey != null);
// Async Flow is enabled and CallContext will be used for ambient transaction.
_threadContextData = CallContextCurrentData.CreateOrGetCurrentData(ContextKey);
{
if (_savedCurrentScope.AsyncFlowEnabled)
{
+ Debug.Assert(_savedCurrentScope.ContextKey != null);
_threadContextData = CallContextCurrentData.CreateOrGetCurrentData(_savedCurrentScope.ContextKey);
}
else
// prevent restoring the context in an unexpected thread due to thread switch during TransactionScope's Dispose
if (shouldRestoreContextData)
{
+ Debug.Assert(_threadContextData != null);
_threadContextData.CurrentScope = _savedCurrentScope;
RestoreCurrent();
}
// SetCurrent
//
// Place the given value in current by whatever means necessary for interop mode.
- private void SetCurrent(Transaction newCurrent)
+ private void SetCurrent(Transaction? newCurrent)
{
// Keep a dependent clone of current if we don't have one and we are not committable
if (_dependentTransaction == null && _committableTransaction == null)
switch (_interopOption)
{
case EnterpriseServicesInteropOption.None:
- _threadContextData.CurrentTransaction = newCurrent;
+ _threadContextData!.CurrentTransaction = newCurrent;
break;
case EnterpriseServicesInteropOption.Automatic:
}
else
{
- _threadContextData.CurrentTransaction = newCurrent;
+ _threadContextData!.CurrentTransaction = newCurrent;
}
break;
}
// Only restore the value that was actually in the context.
- _threadContextData.CurrentTransaction = _contextTransaction;
+ _threadContextData!.CurrentTransaction = _contextTransaction;
}
// ValidateScopeTimeout
//
// Scope timeouts are not governed by MaxTimeout and therefore need a special validate function
- private void ValidateScopeTimeout(string paramName, TimeSpan scopeTimeout)
+ private void ValidateScopeTimeout(string? paramName, TimeSpan scopeTimeout)
{
if (scopeTimeout < TimeSpan.Zero)
{
}
// Storage location for the previous current transaction.
- private Transaction _savedCurrent;
+ private Transaction? _savedCurrent;
// To ensure that we don't restore a value for current that was
// returned to us by an external entity keep the value that was actually
// in TLS when the scope was created.
- private Transaction _contextTransaction;
+ private Transaction? _contextTransaction;
// Storage for the value to restore to current
- private TransactionScope _savedCurrentScope;
+ private TransactionScope? _savedCurrentScope;
// Store a reference to the context data object for this scope.
- private ContextData _threadContextData;
+ private ContextData? _threadContextData;
- private ContextData _savedTLSContextData;
+ private ContextData? _savedTLSContextData;
// Store a reference to the value that this scope expects for current
- private Transaction _expectedCurrent;
+ private Transaction? _expectedCurrent;
// Store a reference to the committable form of this transaction if
// the scope made one.
- private CommittableTransaction _committableTransaction;
+ private CommittableTransaction? _committableTransaction;
// Store a reference to the scopes transaction guard.
- private DependentTransaction _dependentTransaction;
+ private DependentTransaction? _dependentTransaction;
// Note when the scope is disposed.
private bool _disposed;
// BUGBUG: A shared timer should be used.
// Individual timer for this scope.
- private Timer _scopeTimer;
+ private Timer? _scopeTimer;
// Store a reference to the thread on which the scope was created so that we can
// check to make sure that the dispose pattern for scope is being used correctly.
- private Thread _scopeThread;
+ private Thread? _scopeThread;
// Store the interop mode for this transaction scope.
private bool _interopModeSpecified = false;
}
}
- internal ContextKey ContextKey
+ internal ContextKey? ContextKey
{
get;
private set;
// The state machines themselves are designed to be internally consistent. So the only externally visable
// state transition is to active. All other state transitions must happen within the state machines
// themselves.
- private static TransactionStateActive s_transactionStateActive;
- private static TransactionStateSubordinateActive s_transactionStateSubordinateActive;
- private static TransactionStatePhase0 s_transactionStatePhase0;
- private static TransactionStateVolatilePhase1 s_transactionStateVolatilePhase1;
- private static TransactionStateVolatileSPC s_transactionStateVolatileSPC;
- private static TransactionStateSPC s_transactionStateSPC;
- private static TransactionStateAborted s_transactionStateAborted;
- private static TransactionStateCommitted s_transactionStateCommitted;
- private static TransactionStateInDoubt s_transactionStateInDoubt;
-
- private static TransactionStatePromoted s_transactionStatePromoted;
- private static TransactionStateNonCommittablePromoted s_transactionStateNonCommittablePromoted;
- private static TransactionStatePromotedP0Wave s_transactionStatePromotedP0Wave;
- private static TransactionStatePromotedCommitting s_transactionStatePromotedCommitting;
- private static TransactionStatePromotedPhase0 s_transactionStatePromotedPhase0;
- private static TransactionStatePromotedPhase1 s_transactionStatePromotedPhase1;
- private static TransactionStatePromotedP0Aborting s_transactionStatePromotedP0Aborting;
- private static TransactionStatePromotedP1Aborting s_transactionStatePromotedP1Aborting;
- private static TransactionStatePromotedAborted s_transactionStatePromotedAborted;
- private static TransactionStatePromotedCommitted s_transactionStatePromotedCommitted;
- private static TransactionStatePromotedIndoubt s_transactionStatePromotedIndoubt;
-
- private static TransactionStateDelegated s_transactionStateDelegated;
- private static TransactionStateDelegatedSubordinate s_transactionStateDelegatedSubordinate;
- private static TransactionStateDelegatedP0Wave s_transactionStateDelegatedP0Wave;
- private static TransactionStateDelegatedCommitting s_transactionStateDelegatedCommitting;
- private static TransactionStateDelegatedAborting s_transactionStateDelegatedAborting;
- private static TransactionStatePSPEOperation s_transactionStatePSPEOperation;
-
- private static TransactionStateDelegatedNonMSDTC s_transactionStateDelegatedNonMSDTC;
- private static TransactionStatePromotedNonMSDTCPhase0 s_transactionStatePromotedNonMSDTCPhase0;
- private static TransactionStatePromotedNonMSDTCVolatilePhase1 s_transactionStatePromotedNonMSDTCVolatilePhase1;
- private static TransactionStatePromotedNonMSDTCSinglePhaseCommit s_transactionStatePromotedNonMSDTCSinglePhaseCommit;
- private static TransactionStatePromotedNonMSDTCAborted s_transactionStatePromotedNonMSDTCAborted;
- private static TransactionStatePromotedNonMSDTCCommitted s_transactionStatePromotedNonMSDTCCommitted;
- private static TransactionStatePromotedNonMSDTCIndoubt s_transactionStatePromotedNonMSDTCIndoubt;
+ private static TransactionStateActive? s_transactionStateActive;
+ private static TransactionStateSubordinateActive? s_transactionStateSubordinateActive;
+ private static TransactionStatePhase0? s_transactionStatePhase0;
+ private static TransactionStateVolatilePhase1? s_transactionStateVolatilePhase1;
+ private static TransactionStateVolatileSPC? s_transactionStateVolatileSPC;
+ private static TransactionStateSPC? s_transactionStateSPC;
+ private static TransactionStateAborted? s_transactionStateAborted;
+ private static TransactionStateCommitted? s_transactionStateCommitted;
+ private static TransactionStateInDoubt? s_transactionStateInDoubt;
+
+ private static TransactionStatePromoted? s_transactionStatePromoted;
+ private static TransactionStateNonCommittablePromoted? s_transactionStateNonCommittablePromoted;
+ private static TransactionStatePromotedP0Wave? s_transactionStatePromotedP0Wave;
+ private static TransactionStatePromotedCommitting? s_transactionStatePromotedCommitting;
+ private static TransactionStatePromotedPhase0? s_transactionStatePromotedPhase0;
+ private static TransactionStatePromotedPhase1? s_transactionStatePromotedPhase1;
+ private static TransactionStatePromotedP0Aborting? s_transactionStatePromotedP0Aborting;
+ private static TransactionStatePromotedP1Aborting? s_transactionStatePromotedP1Aborting;
+ private static TransactionStatePromotedAborted? s_transactionStatePromotedAborted;
+ private static TransactionStatePromotedCommitted? s_transactionStatePromotedCommitted;
+ private static TransactionStatePromotedIndoubt? s_transactionStatePromotedIndoubt;
+
+ private static TransactionStateDelegated? s_transactionStateDelegated;
+ private static TransactionStateDelegatedSubordinate? s_transactionStateDelegatedSubordinate;
+ private static TransactionStateDelegatedP0Wave? s_transactionStateDelegatedP0Wave;
+ private static TransactionStateDelegatedCommitting? s_transactionStateDelegatedCommitting;
+ private static TransactionStateDelegatedAborting? s_transactionStateDelegatedAborting;
+ private static TransactionStatePSPEOperation? s_transactionStatePSPEOperation;
+
+ private static TransactionStateDelegatedNonMSDTC? s_transactionStateDelegatedNonMSDTC;
+ private static TransactionStatePromotedNonMSDTCPhase0? s_transactionStatePromotedNonMSDTCPhase0;
+ private static TransactionStatePromotedNonMSDTCVolatilePhase1? s_transactionStatePromotedNonMSDTCVolatilePhase1;
+ private static TransactionStatePromotedNonMSDTCSinglePhaseCommit? s_transactionStatePromotedNonMSDTCSinglePhaseCommit;
+ private static TransactionStatePromotedNonMSDTCAborted? s_transactionStatePromotedNonMSDTCAborted;
+ private static TransactionStatePromotedNonMSDTCCommitted? s_transactionStatePromotedNonMSDTCCommitted;
+ private static TransactionStatePromotedNonMSDTCIndoubt? s_transactionStatePromotedNonMSDTCIndoubt;
// Object for synchronizing access to the entire class( avoiding lock( typeof( ... )) )
- internal static object s_classSyncObject;
+ internal static object? s_classSyncObject;
internal static TransactionStateActive TransactionStateActive =>
LazyInitializer.EnsureInitialized(ref s_transactionStateActive, ref s_classSyncObject, () => new TransactionStateActive());
// Every state must override EnterState
internal abstract void EnterState(InternalTransaction tx);
- internal virtual void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal virtual void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
}
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
}
- internal virtual void Rollback(InternalTransaction tx, Exception e)
+ internal virtual void Rollback(InternalTransaction tx, Exception? e)
{
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
}
// Every state derived from the base must override status
internal abstract TransactionStatus get_Status(InternalTransaction tx);
- internal virtual void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler transactionCompletedDelegate)
+ internal virtual void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler? transactionCompletedDelegate)
{
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
}
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
}
- internal virtual void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal virtual void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
Debug.Fail($"Invalid Event for State; Current State: {GetType()}");
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
return TransactionStatus.Active;
}
- internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler transactionCompletedDelegate)
+ internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler? transactionCompletedDelegate)
{
- tx._transactionCompletedDelegate = (TransactionCompletedEventHandler)
+ tx._transactionCompletedDelegate = (TransactionCompletedEventHandler?)
System.Delegate.Combine(tx._transactionCompletedDelegate, transactionCompletedDelegate);
}
}
tx._promoteState.EnterState(tx);
// Note that just because we did an EnterState above does not mean that the state will be
// the same when the next method is called.
- return tx.State.EnlistDurable(tx, resourceManagerIdentifier, enlistmentNotification, enlistmentOptions, atomicTransaction);
+ return tx.State!.EnlistDurable(tx, resourceManagerIdentifier, enlistmentNotification, enlistmentOptions, atomicTransaction);
}
internal override Enlistment EnlistDurable(
{
// These circumstances cause promotion
tx._promoteState.EnterState(tx);
- return tx.State.EnlistDurable(tx, resourceManagerIdentifier, enlistmentNotification, enlistmentOptions, atomicTransaction);
+ return tx.State!.EnlistDurable(tx, resourceManagerIdentifier, enlistmentNotification, enlistmentOptions, atomicTransaction);
}
// Create a durable enlistment
tx._promoteState.EnterState(tx);
// Forward this call
- tx.State.GetObjectData(tx, serializationInfo, context);
+ tx.State!.GetObjectData(tx, serializationInfo, context);
}
internal override void CompleteBlockingClone(InternalTransaction tx)
if (tx._phase0Volatiles._preparedVolatileEnlistments ==
tx._phase0VolatileWaveCount + tx._phase0Volatiles._dependentClones)
{
- tx.State.Phase0VolatilePrepareDone(tx);
+ tx.State!.Phase0VolatilePrepareDone(tx);
}
}
internal override void Promote(InternalTransaction tx)
{
tx._promoteState.EnterState(tx);
- tx.State.CheckForFinishedTransaction(tx);
+ tx.State!.CheckForFinishedTransaction(tx);
}
internal override byte[] PromotedToken(InternalTransaction tx)
if (tx.promotedToken == null)
{
tx._promoteState.EnterState(tx);
- tx.State.CheckForFinishedTransaction(tx);
+ tx.State!.CheckForFinishedTransaction(tx);
}
-
+ Debug.Assert(tx.promotedToken != null);
return tx.promotedToken;
}
}
// Yeah it's active.
}
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
// Store the given values
tx._asyncCommit = asyncCommit;
TransactionStatePhase0.EnterState(tx);
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
// Start the process for abort. From the active state we can transition directly
// to the aborted state.
internal override void DisposeRoot(InternalTransaction tx)
{
- tx.State.Rollback(tx, null);
+ tx.State!.Rollback(tx, null);
}
}
Debug.Assert(tx._promoter != null, "Transaction Promoter is Null entering SubordinateActive");
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
// Start the process for abort. From the active state we can transition directly
// to the aborted state.
tx._innerException = e;
}
+ Debug.Assert(tx._promoter != null);
((ISimpleTransactionSuperior)tx._promoter).Rollback();
TransactionStateAborted.EnterState(tx);
}
)
{
tx._promoteState.EnterState(tx);
- return tx.State.EnlistVolatile(tx, enlistmentNotification, enlistmentOptions, atomicTransaction);
+ return tx.State!.EnlistVolatile(tx, enlistmentNotification, enlistmentOptions, atomicTransaction);
}
internal override Enlistment EnlistVolatile(
)
{
tx._promoteState.EnterState(tx);
- return tx.State.EnlistVolatile(tx, enlistmentNotification, enlistmentOptions, atomicTransaction);
+ return tx.State!.EnlistVolatile(tx, enlistmentNotification, enlistmentOptions, atomicTransaction);
}
// Every state derived from the base must override status
internal override TransactionStatus get_Status(InternalTransaction tx)
{
tx._promoteState.EnterState(tx);
- return tx.State.get_Status(tx);
+ return tx.State!.get_Status(tx);
}
- internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler transactionCompletedDelegate)
+ internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler? transactionCompletedDelegate)
{
tx._promoteState.EnterState(tx);
- tx.State.AddOutcomeRegistrant(tx, transactionCompletedDelegate);
+ tx.State!.AddOutcomeRegistrant(tx, transactionCompletedDelegate);
}
internal override bool EnlistPromotableSinglePhase(
internal override void CreateBlockingClone(InternalTransaction tx)
{
tx._promoteState.EnterState(tx);
- tx.State.CreateBlockingClone(tx);
+ tx.State!.CreateBlockingClone(tx);
}
internal override void CreateAbortingClone(InternalTransaction tx)
{
tx._promoteState.EnterState(tx);
- tx.State.CreateAbortingClone(tx);
+ tx.State!.CreateAbortingClone(tx);
}
}
// Broadcast prepare to the phase 0 enlistments
for (int i = 0; i < volatileCount; i++)
{
- tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState.ChangeStatePreparing(tx._phase0Volatiles._volatileEnlistments[i]);
- if (!tx.State.ContinuePhase0Prepares())
+ tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState!.ChangeStatePreparing(tx._phase0Volatiles._volatileEnlistments[i]);
+ if (!tx.State!.ContinuePhase0Prepares())
{
break;
}
enlistmentOptions, atomicTransaction);
// Calling durable enlist in Phase0 may cause the transaction to promote. Leverage the promoted
- tx.State.RestartCommitIfNeeded(tx);
+ tx.State!.RestartCommitIfNeeded(tx);
return en;
}
enlistmentOptions, atomicTransaction);
// Calling durable enlist in Phase0 may cause the transaction to promote. Leverage the promoted
- tx.State.RestartCommitIfNeeded(tx);
+ tx.State!.RestartCommitIfNeeded(tx);
return en;
}
return enlistment;
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
ChangeStateTransactionAborted(tx, e);
}
// Broadcast prepare to the phase 0 enlistments
for (int i = 0; i < volatileCount; i++)
{
- tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState.ChangeStatePreparing(tx._phase0Volatiles._volatileEnlistments[i]);
- if (!tx.State.ContinuePhase0Prepares())
+ tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState!.ChangeStatePreparing(tx._phase0Volatiles._volatileEnlistments[i]);
+ if (!tx.State!.ContinuePhase0Prepares())
{
break;
}
internal override void Promote(InternalTransaction tx)
{
tx._promoteState.EnterState(tx);
- tx.State.CheckForFinishedTransaction(tx);
+ tx.State!.CheckForFinishedTransaction(tx);
tx.State.RestartCommitIfNeeded(tx);
}
- internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
if (tx._innerException == null)
{
tx._promoteState.EnterState(tx);
// Forward this call
- tx.State.GetObjectData(tx, serializationInfo, context);
+ tx.State!.GetObjectData(tx, serializationInfo, context);
// Restart the commit process.
tx.State.RestartCommitIfNeeded(tx);
// Set the transaction state
CommonEnterState(tx);
+ Debug.Assert(tx._committableTransaction != null);
// Mark the committable transaction as complete.
tx._committableTransaction._complete = true;
// Broadcast prepare to the phase 0 enlistments
for (int i = 0; i < tx._phase1Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState.ChangeStatePreparing(tx._phase1Volatiles._volatileEnlistments[i]);
- if (!tx.State.ContinuePhase1Prepares())
+ tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState!.ChangeStatePreparing(tx._phase1Volatiles._volatileEnlistments[i]);
+ if (!tx.State!.ContinuePhase1Prepares())
{
break;
}
}
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
ChangeStateTransactionAborted(tx, e);
}
- internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
if (tx._innerException == null)
{
Debug.Assert(tx._phase1Volatiles._volatileEnlistmentCount == 1,
"There must be exactly 1 phase 1 volatile enlistment for TransactionStateVolatileSPC");
- tx._phase1Volatiles._volatileEnlistments[0]._twoPhaseState.ChangeStateSinglePhaseCommit(
+ tx._phase1Volatiles._volatileEnlistments[0]._twoPhaseState!.ChangeStateSinglePhaseCommit(
tx._phase1Volatiles._volatileEnlistments[0]);
}
TransactionStateInDoubt.EnterState(tx);
}
- internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
if (tx._innerException == null)
{
TransactionStateInDoubt.EnterState(tx);
}
- internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
if (tx._innerException == null)
{
}
}
- internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler transactionCompletedDelegate)
+ internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler? transactionCompletedDelegate)
{
if (transactionCompletedDelegate != null)
{
// Notify the enlistments that the transaction has aborted
for (int i = 0; i < tx._phase0Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState.InternalAborted(tx._phase0Volatiles._volatileEnlistments[i]);
+ tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState!.InternalAborted(tx._phase0Volatiles._volatileEnlistments[i]);
}
for (int i = 0; i < tx._phase1Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState.InternalAborted(tx._phase1Volatiles._volatileEnlistments[i]);
+ tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState!.InternalAborted(tx._phase1Volatiles._volatileEnlistments[i]);
}
// Notify the durable enlistment
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
// Abort is itempotent. Ignore this if the transaction is already aborted.
}
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
// End Commit Must throw a TransactionAbortedException to let the caller know that the tx aborted.
throw CreateTransactionAbortedException(tx);
// Since the transaction is aborted ignore it.
}
- internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
// Yes, yes, yes... I already know.
}
// Notify the phase 0 enlistments that the transaction has aborted
for (int i = 0; i < tx._phase0Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState.InternalCommitted(tx._phase0Volatiles._volatileEnlistments[i]);
+ tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState!.InternalCommitted(tx._phase0Volatiles._volatileEnlistments[i]);
}
// Notify the phase 1 enlistments that the transaction has aborted
for (int i = 0; i < tx._phase1Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState.InternalCommitted(tx._phase1Volatiles._volatileEnlistments[i]);
+ tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState!.InternalCommitted(tx._phase1Volatiles._volatileEnlistments[i]);
}
// Remove this from the timeout list
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
}
// Notify the phase 0 enlistments that the transaction has aborted
for (int i = 0; i < tx._phase0Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState.InternalIndoubt(tx._phase0Volatiles._volatileEnlistments[i]);
+ tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState!.InternalIndoubt(tx._phase0Volatiles._volatileEnlistments[i]);
}
// Notify the phase 1 enlistments that the transaction has aborted
for (int i = 0; i < tx._phase1Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState.InternalIndoubt(tx._phase1Volatiles._volatileEnlistments[i]);
+ tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState!.InternalIndoubt(tx._phase1Volatiles._volatileEnlistments[i]);
}
// Remove this from the timeout list
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
}
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
Debug.Assert(tx.PromotedTransaction != null, "Promoted state not valid for transaction.");
// Forward this on to the promoted transaction.
}
- internal override Guid get_Identifier(InternalTransaction tx)
+ internal override Guid get_Identifier(InternalTransaction? tx)
{
if (tx != null && tx.PromotedTransaction != null)
{
}
- internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler transactionCompletedDelegate)
+ internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler? transactionCompletedDelegate)
{
// Add this guy to the list of people to be notified of the outcome.
- tx._transactionCompletedDelegate = (TransactionCompletedEventHandler)
+ tx._transactionCompletedDelegate = (TransactionCompletedEventHandler?)
System.Delegate.Combine(tx._transactionCompletedDelegate, transactionCompletedDelegate);
}
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
// Store the given values
tx._asyncCommit = asyncCommit;
if (tx._phase0Volatiles._preparedVolatileEnlistments ==
tx._phase0VolatileWaveCount + tx._phase0Volatiles._dependentClones)
{
- tx.State.Phase0VolatilePrepareDone(tx);
+ tx.State!.Phase0VolatilePrepareDone(tx);
}
}
else
Debug.Assert(tx._phase0WaveDependentCloneCount >= 0);
if (tx._phase0WaveDependentCloneCount == 0)
{
- DistributedDependentTransaction dtx = tx._phase0WaveDependentClone;
+ DistributedDependentTransaction dtx = tx._phase0WaveDependentClone!;
tx._phase0WaveDependentClone = null;
Monitor.Exit(tx);
{
// We need to complete our dependent clone on the promoted transaction and null it out
// so if we get a new one, a new one will be created on the promoted transaction.
- DistributedDependentTransaction dtx = tx._abortingDependentClone;
+ DistributedDependentTransaction dtx = tx._abortingDependentClone!;
tx._abortingDependentClone = null;
Monitor.Exit(tx);
// will handle phase 0 waves.
if (tx._phase0WaveDependentClone == null)
{
+ Debug.Assert(tx.PromotedTransaction != null);
tx._phase0WaveDependentClone = tx.PromotedTransaction.DependentClone(true);
}
{
if (null == tx._abortingDependentClone)
{
+ Debug.Assert(tx.PromotedTransaction != null);
tx._abortingDependentClone = tx.PromotedTransaction.DependentClone(false);
}
tx._abortingDependentCloneCount++;
// Before forwarding this call to the promoted tx make sure to change
// the full type info so that only if the promoted tx does not set this
// then it should be set correctly.
- serializationInfo.FullTypeName = tx.PromotedTransaction.GetType().FullName;
+ serializationInfo.FullTypeName = tx.PromotedTransaction.GetType().FullName!;
// Now forward the call.
serializableTx.GetObjectData(serializationInfo, context);
if (tx._innerException == null)
{
tx._innerException = new TimeoutException(SR.TraceTransactionTimeout);
- ;
}
+ Debug.Assert(tx.PromotedTransaction != null);
tx.PromotedTransaction.Rollback();
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
// Set the transaction state
CommonEnterState(tx);
+ Debug.Assert(tx.PromotedTransaction != null && tx.PromotedTransaction.RealTransaction != null);
// Let the distributed transaction know that we want to know about the outcome.
tx.PromotedTransaction.RealTransaction.InternalTransaction = tx;
}
CommonEnterState(tx);
// Create a transaction with the distributed transaction manager
- DistributedCommittableTransaction distributedTx = null;
+ DistributedCommittableTransaction? distributedTx = null;
try
{
TimeSpan newTimeout;
{
// There was an exception trying to create the distributed transaction abort
// the local transaction and exit.
- tx.State.ChangeStateAbortedDuringPromotion(tx);
+ tx.State!.ChangeStateAbortedDuringPromotion(tx);
}
}
volatiles.VolatileDemux = new Phase1VolatileDemultiplexer(tx);
}
+ Debug.Assert(tx.PromotedTransaction != null);
volatiles.VolatileDemux._promotedEnlistment = tx.PromotedTransaction.EnlistVolatile(volatiles.VolatileDemux,
phase0 ? EnlistmentOptions.EnlistDuringPrepareRequired : EnlistmentOptions.None);
}
{
// Directly enlist the durable enlistment with the resource manager.
InternalEnlistment enlistment = tx._durableEnlistment;
+ Debug.Assert(tx.PromotedTransaction != null);
IPromotedEnlistment promotedEnlistment = tx.PromotedTransaction.EnlistDurable(
enlistment.ResourceManagerIdentifier,
(DurableInternalEnlistment)enlistment,
bool enlistmentsPromoted = false;
+ Debug.Assert(tx.PromotedTransaction != null && tx.PromotedTransaction.RealTransaction != null);
// Tell the real transaction that we want a callback for the outcome.
tx.PromotedTransaction.RealTransaction.InternalTransaction = tx;
+ Debug.Assert(tx.State != null);
// Promote Phase 0 Volatiles
try
{
internal override void DisposeRoot(InternalTransaction tx)
{
- tx.State.Rollback(tx, null);
+ tx.State!.Rollback(tx, null);
}
}
}
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
// Don't allow this again.
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
}
- internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
if (tx._innerException == null)
{
CommonEnterState(tx);
// Use the asynchronous commit provided by the promoted transaction
- var ctx = (DistributedCommittableTransaction)tx.PromotedTransaction;
+ var ctx = (DistributedCommittableTransaction)tx.PromotedTransaction!;
ctx.BeginCommit(tx);
}
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
// Don't allow this again.
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
// Broadcast preprepare to the volatile subordinates
for (int i = 0; i < volatileCount; i++)
{
- tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState.ChangeStatePreparing(
+ tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState!.ChangeStatePreparing(
tx._phase0Volatiles._volatileEnlistments[i]);
- if (!tx.State.ContinuePhase0Prepares())
+ if (!tx.State!.ContinuePhase0Prepares())
{
break;
}
Monitor.Exit(tx);
try
{
+ Debug.Assert(tx._phase0Volatiles.VolatileDemux._promotedEnlistment != null);
// Tell the distributed TM that the volatile enlistments are prepared
tx._phase0Volatiles.VolatileDemux._promotedEnlistment.Prepared();
}
}
- internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
if (tx._innerException == null)
{
// If at this point there are phase1 dependent clones abort the transaction
if (tx._phase1Volatiles._dependentClones != 0)
{
- tx.State.ChangeStateTransactionAborted(tx, null);
+ tx.State!.ChangeStateTransactionAborted(tx, null);
return;
}
// Broadcast preprepare to the volatile subordinates
for (int i = 0; i < volatileCount; i++)
{
- tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState.ChangeStatePreparing(
+ tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState!.ChangeStatePreparing(
tx._phase1Volatiles._volatileEnlistments[i]);
- if (!tx.State.ContinuePhase1Prepares())
+ if (!tx.State!.ContinuePhase1Prepares())
{
break;
}
}
- internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
if (tx._innerException == null)
{
Monitor.Exit(tx);
try
{
+ Debug.Assert(tx._phase1Volatiles.VolatileDemux._promotedEnlistment != null);
// Tell the distributed TM that the volatile enlistments are prepared
tx._phase1Volatiles.VolatileDemux._promotedEnlistment.Prepared();
}
}
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
// Don't allow this again.
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
}
- internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
// Don't do this yet wait until all of the notifications come back.
}
Monitor.Exit(tx);
try
{
+ Debug.Assert(tx._phase0Volatiles.VolatileDemux._promotedEnlistment != null);
// Tell the distributed TM that the tx aborted.
tx._phase0Volatiles.VolatileDemux._promotedEnlistment.ForceRollback();
}
}
else
{
+ Debug.Assert(tx.PromotedTransaction != null);
// Otherwise make sure that the transaction rolls back.
tx.PromotedTransaction.Rollback();
}
Monitor.Exit(tx);
try
{
+ Debug.Assert(tx._phase1Volatiles.VolatileDemux._promotedEnlistment != null);
// Tell the distributed TM that the tx aborted.
tx._phase1Volatiles.VolatileDemux._promotedEnlistment.ForceRollback();
}
}
- internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler transactionCompletedDelegate)
+ internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler? transactionCompletedDelegate)
{
if (transactionCompletedDelegate != null)
{
internal override Guid get_Identifier(InternalTransaction tx)
{
+ Debug.Assert(tx.PromotedTransaction != null);
return tx.PromotedTransaction.Identifier;
}
protected abstract void PromotedTransactionOutcome(InternalTransaction tx);
- private static WaitCallback s_signalMethod;
- private static WaitCallback SignalMethod => LazyInitializer.EnsureInitialized(ref s_signalMethod, ref s_classSyncObject, () => new WaitCallback(SignalCallback));
+ private static WaitCallback? s_signalMethod;
+ private static WaitCallback SignalMethod => LazyInitializer.EnsureInitialized(ref s_signalMethod, ref s_classSyncObject, () => new WaitCallback(SignalCallback!));
private static void SignalCallback(object state)
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
// Already done.
}
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
throw TransactionAbortedException.Create(SR.TransactionAborted, tx._innerException, tx.DistributedTxId);
}
}
- internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
// This may come from a promotable single phase enlistments abort response.
}
CommonEnterState(tx);
// Create a transaction with the distributed transaction manager
- DistributedTransaction distributedTx = null;
+ DistributedTransaction? distributedTx = null;
try
{
// Ask the delegation interface to promote the transaction.
}
finally
{
- if (((object)distributedTx) == null)
+ if (((object?)distributedTx) == null)
{
// There was an exception trying to create the distributed transaction abort
// the local transaction and exit.
- tx.State.ChangeStateAbortedDuringPromotion(tx);
+ tx.State!.ChangeStateAbortedDuringPromotion(tx);
}
}
- if (((object)distributedTx) == null)
+ if (((object?)distributedTx) == null)
{
return;
}
// except for the way that commit happens.
internal class TransactionStateDelegated : TransactionStateDelegatedBase
{
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
// Store the given values
tx._asyncCommit = asyncCommit;
internal override bool PromoteDurable(InternalTransaction tx)
{
+ Debug.Assert(tx._durableEnlistment != null);
// Let the enlistment know that it has been delegated. For this type of enlistment that
// is really all that needs to be done.
tx._durableEnlistment.State.ChangeStateDelegated(tx._durableEnlistment);
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
// Pass the Rollback through the promotable single phase enlistment to be
// certain it is notified.
return false;
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
// Start the process for abort. Transitioning to the Aborted state will cause
// the tx.durableEnlistment to get aborted, which is how the non-MSDTC
}
- internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler transactionCompletedDelegate)
+ internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler? transactionCompletedDelegate)
{
// Add this guy to the list of people to be notified of the outcome.
- tx._transactionCompletedDelegate = (TransactionCompletedEventHandler)
+ tx._transactionCompletedDelegate = (TransactionCompletedEventHandler?)
System.Delegate.Combine(tx._transactionCompletedDelegate, transactionCompletedDelegate);
}
// Start the commit processing by transitioning to TransactionStatePromotedNonMSDTCPhase0.
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
tx._asyncCommit = asyncCommit;
tx._asyncCallback = asyncCallback;
if (tx._phase0Volatiles._preparedVolatileEnlistments ==
tx._phase0VolatileWaveCount + tx._phase0Volatiles._dependentClones)
{
- tx.State.Phase0VolatilePrepareDone(tx);
+ tx.State!.Phase0VolatilePrepareDone(tx);
}
}
}
tx._innerException);
}
- internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
// Just transition to Aborted. The PSPE will be told to rollback thru the durableEnlistment.
// This is also overridden in TransactionStatePromotedNonMSDTCSinglePhaseCommit
internal override void DisposeRoot(InternalTransaction tx)
{
- tx.State.Rollback(tx, null);
+ tx.State!.Rollback(tx, null);
}
}
// Broadcast prepare to the phase 0 enlistments
for (int i = 0; i < volatileCount; i++)
{
- tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState.ChangeStatePreparing(tx._phase0Volatiles._volatileEnlistments[i]);
- if (!tx.State.ContinuePhase0Prepares())
+ tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState!.ChangeStatePreparing(tx._phase0Volatiles._volatileEnlistments[i]);
+ if (!tx.State!.ContinuePhase0Prepares())
{
break;
}
}
}
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
ChangeStateTransactionAborted(tx, e);
}
// Broadcast prepare to the phase 0 enlistments
for (int i = 0; i < volatileCount; i++)
{
- tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState.ChangeStatePreparing(tx._phase0Volatiles._volatileEnlistments[i]);
- if (!tx.State.ContinuePhase0Prepares())
+ tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState!.ChangeStatePreparing(tx._phase0Volatiles._volatileEnlistments[i]);
+ if (!tx.State!.ContinuePhase0Prepares())
{
break;
}
// Set the transaction state
CommonEnterState(tx);
+ Debug.Assert(tx._committableTransaction != null);
// Mark the committable transaction as complete.
tx._committableTransaction._complete = true;
// Broadcast prepare to the phase 0 enlistments
for (int i = 0; i < tx._phase1Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState.ChangeStatePreparing(tx._phase1Volatiles._volatileEnlistments[i]);
- if (!tx.State.ContinuePhase1Prepares())
+ tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState!.ChangeStatePreparing(tx._phase1Volatiles._volatileEnlistments[i]);
+ if (!tx.State!.ContinuePhase1Prepares())
{
break;
}
}
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
ChangeStateTransactionAborted(tx, e);
}
{
CommonEnterState(tx);
+ Debug.Assert(tx._durableEnlistment != null);
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
{
tx._durableEnlistment.State.ChangeStateCommitting(tx._durableEnlistment);
}
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
// We have told the PSPE enlistment to do a single phase commit. It's too late to rollback.
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
TransactionStatePromotedNonMSDTCIndoubt.EnterState(tx);
}
- internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
if (tx._innerException == null)
{
}
}
- internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler transactionCompletedDelegate)
+ internal override void AddOutcomeRegistrant(InternalTransaction tx, TransactionCompletedEventHandler? transactionCompletedDelegate)
{
if (transactionCompletedDelegate != null)
{
protected abstract void PromotedTransactionOutcome(InternalTransaction tx);
- private static WaitCallback s_signalMethod;
- private static WaitCallback SignalMethod => LazyInitializer.EnsureInitialized(ref s_signalMethod, ref s_classSyncObject, () => new WaitCallback(SignalCallback));
+ private static WaitCallback? s_signalMethod;
+ private static WaitCallback SignalMethod => LazyInitializer.EnsureInitialized(ref s_signalMethod, ref s_classSyncObject, () => new WaitCallback(SignalCallback!));
private static void SignalCallback(object state)
{
// Notify the enlistments that the transaction has aborted
for (int i = 0; i < tx._phase0Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState.InternalAborted(tx._phase0Volatiles._volatileEnlistments[i]);
+ tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState!.InternalAborted(tx._phase0Volatiles._volatileEnlistments[i]);
}
for (int i = 0; i < tx._phase1Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState.InternalAborted(tx._phase1Volatiles._volatileEnlistments[i]);
+ tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState!.InternalAborted(tx._phase1Volatiles._volatileEnlistments[i]);
}
// Notify the durable enlistment
return TransactionStatus.Aborted;
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
// Already done.
}
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
throw TransactionAbortedException.Create(SR.TransactionAborted, tx._innerException, tx.DistributedTxId);
}
// Since the transaction is aborted ignore it.
}
- internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception e)
+ internal override void ChangeStateTransactionAborted(InternalTransaction tx, Exception? e)
{
// This may come from a promotable single phase enlistments abort response.
}
// Notify the phase 0 enlistments that the transaction has committed
for (int i = 0; i < tx._phase0Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState.InternalCommitted(tx._phase0Volatiles._volatileEnlistments[i]);
+ tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState!.InternalCommitted(tx._phase0Volatiles._volatileEnlistments[i]);
}
// Notify the phase 1 enlistments that the transaction has committed
for (int i = 0; i < tx._phase1Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState.InternalCommitted(tx._phase1Volatiles._volatileEnlistments[i]);
+ tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState!.InternalCommitted(tx._phase1Volatiles._volatileEnlistments[i]);
}
// Fire Completion for anyone listening
// Notify the phase 0 enlistments that the transaction is indoubt
for (int i = 0; i < tx._phase0Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState.InternalIndoubt(tx._phase0Volatiles._volatileEnlistments[i]);
+ tx._phase0Volatiles._volatileEnlistments[i]._twoPhaseState!.InternalIndoubt(tx._phase0Volatiles._volatileEnlistments[i]);
}
// Notify the phase 1 enlistments that the transaction is indoubt
for (int i = 0; i < tx._phase1Volatiles._volatileEnlistmentCount; i++)
{
- tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState.InternalIndoubt(tx._phase1Volatiles._volatileEnlistments[i]);
+ tx._phase1Volatiles._volatileEnlistments[i]._twoPhaseState!.InternalIndoubt(tx._phase1Volatiles._volatileEnlistments[i]);
}
// Fire Completion for anyone listening
CommonEnterState(tx);
// We are never going to have an DistributedTransaction for this one.
- DistributedTransaction distributedTx = null;
+ DistributedTransaction? distributedTx = null;
try
{
// Ask the delegation interface to promote the transaction.
if (tx.promotedToken == null)
{
// There was an exception trying to promote the transaction.
- tx.State.ChangeStateAbortedDuringPromotion(tx);
+ tx.State!.ChangeStateAbortedDuringPromotion(tx);
}
}
}
}
- internal override void Rollback(InternalTransaction tx, Exception e)
+ internal override void Rollback(InternalTransaction tx, Exception? e)
{
// Pass the Rollback through the promotable single phase enlistment to be
// certain it is notified.
tx._innerException = e;
}
+ Debug.Assert(tx.PromotedTransaction != null);
tx.PromotedTransaction.Rollback();
TransactionStatePromotedAborted.EnterState(tx);
}
}
}
- internal DistributedTransaction PSPEPromote(InternalTransaction tx)
+ internal DistributedTransaction? PSPEPromote(InternalTransaction tx)
{
bool changeToReturnState = true;
- TransactionState returnState = tx.State;
+ TransactionState? returnState = tx.State;
Debug.Assert(returnState == TransactionStateDelegated ||
returnState == TransactionStateDelegatedSubordinate ||
returnState == TransactionStateDelegatedNonMSDTC,
"PSPEPromote called from state other than TransactionStateDelegated[NonMSDTC]");
CommonEnterState(tx);
- DistributedTransaction distributedTx = null;
+ DistributedTransaction? distributedTx = null;
try
{
if (tx._attemptingPSPEPromote)
}
tx._attemptingPSPEPromote = true;
- byte[] propagationToken = tx._promoter.Promote();
+ Debug.Assert(tx._promoter != null);
+ byte[]? propagationToken = tx._promoter.Promote();
// If the PromoterType is NOT MSDTC, then we can't assume that the returned
// byte[] is an MSDTC propagation token and we can't create an DistributedTransaction from it.
try
{
distributedTx = TransactionInterop.GetDistributedTransactionFromTransmitterPropagationToken(
- propagationToken
+ propagationToken!
);
}
catch (ArgumentException e)
// Now we need to create the durable enlistment that will replace the PSPE enlistment. Use the internalEnlistment of
// this newly created durable enlistment as the tx.durableEnlistment.
- enlistment = tx.State.EnlistDurable(tx, resourceManagerIdentifier, enlistmentNotification, enlistmentOptions, atomicTransaction);
+ enlistment = tx.State!.EnlistDurable(tx, resourceManagerIdentifier, enlistmentNotification, enlistmentOptions, atomicTransaction);
tx._durableEnlistment = enlistment.InternalEnlistment;
return enlistment;
// Forward this on to the promotable single phase enlisment
Monitor.Exit(tx);
+ Debug.Assert(tx._durableEnlistment != null);
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
{
Monitor.Exit(tx);
try
{
+ Debug.Assert(tx._durableEnlistment != null);
TransactionsEtwProvider etwLog = TransactionsEtwProvider.Log;
if (etwLog.IsEnabled())
{
}
- internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback asyncCallback, object asyncState)
+ internal override void BeginCommit(InternalTransaction tx, bool asyncCommit, AsyncCallback? asyncCallback, object? asyncState)
{
// Initiate the commit process.
throw TransactionException.CreateTransactionStateException(tx._innerException, tx.DistributedTxId);
{
internal class CheapUnfairReaderWriterLock
{
- private object _writerFinishedEvent;
+ private object? _writerFinishedEvent;
private int _readersIn;
private int _readersOut;
private bool _writerPresent;
- private object _syncRoot;
+ private object? _syncRoot;
// Spin lock params
private const int MAX_SPIN_COUNT = 100;
while (currentBucketSet.AbsoluteTimeout != txNew.AbsoluteTimeout)
{
- BucketSet lastBucketSet = null;
+ BucketSet? lastBucketSet = null;
do
{
- WeakReference nextSetWeak = (WeakReference)currentBucketSet.nextSetWeak;
- BucketSet nextBucketSet = null;
+ WeakReference? nextSetWeak = (WeakReference?)currentBucketSet.nextSetWeak;
+ BucketSet? nextBucketSet = null;
if (nextSetWeak != null)
{
- nextBucketSet = (BucketSet)nextSetWeak.Target;
+ nextBucketSet = (BucketSet?)nextSetWeak.Target;
}
if (nextBucketSet == null)
BucketSet newBucketSet = new BucketSet(this, txNew.AbsoluteTimeout);
WeakReference newSetWeak = new WeakReference(newBucketSet);
- WeakReference oldNextSetWeak = (WeakReference)Interlocked.CompareExchange(
+ WeakReference? oldNextSetWeak = (WeakReference?)Interlocked.CompareExchange(
ref currentBucketSet.nextSetWeak, newSetWeak, nextSetWeak);
if (oldNextSetWeak == nextSetWeak)
{
BucketSet newBucketSet = new BucketSet(this, txNew.AbsoluteTimeout);
WeakReference newSetWeak = new WeakReference(newBucketSet);
+ Debug.Assert(lastBucketSet != null);
newBucketSet.nextSetWeak = lastBucketSet.nextSetWeak;
- WeakReference oldNextSetWeak = (WeakReference)Interlocked.CompareExchange(
+ WeakReference? oldNextSetWeak = (WeakReference?)Interlocked.CompareExchange(
ref lastBucketSet.nextSetWeak, newSetWeak, newBucketSet.nextSetWeak);
if (oldNextSetWeak == newBucketSet.nextSetWeak)
{
// Ladies and Gentlemen we have a winner.
if (oldNextSetWeak != null)
{
- BucketSet oldSet = (BucketSet)oldNextSetWeak.Target;
+ BucketSet? oldSet = (BucketSet?)oldNextSetWeak.Target;
if (oldSet != null)
{
// prev references are just there to root things for the GC. If this object is
// Remove a transaction from the table.
internal void Remove(InternalTransaction tx)
{
+ Debug.Assert(tx._tableBucket != null);
tx._tableBucket.Remove(tx);
tx._tableBucket = null;
}
// Process a timer event
- private void ThreadTimer(object state)
+ private void ThreadTimer(object? state)
{
//
// Theory of operation.
// that point will timeout so once we've found it then it is just a matter of traversing the
// structure.
//
- BucketSet lastBucketSet = null;
+ BucketSet? lastBucketSet = null;
BucketSet currentBucketSet = _headBucketSet; // The list always has a head.
// Acquire a writer lock before checking to see if we should disable the timer.
// Adding of transactions acquires a reader lock and might insert a new BucketSet.
// If that races with our check for a BucketSet existing, we may not timeout that
// transaction that is being added.
- WeakReference nextWeakSet = null;
- BucketSet nextBucketSet = null;
+ WeakReference? nextWeakSet = null;
+ BucketSet? nextBucketSet = null;
- nextWeakSet = (WeakReference)currentBucketSet.nextSetWeak;
+ nextWeakSet = (WeakReference?)currentBucketSet.nextSetWeak;
if (nextWeakSet != null)
{
- nextBucketSet = (BucketSet)nextWeakSet.Target;
+ nextBucketSet = (BucketSet?)nextWeakSet.Target;
}
if (nextBucketSet == null)
try
{
// Access the nextBucketSet again in writer lock to account for any race before disabling the timeout.
- nextWeakSet = (WeakReference)currentBucketSet.nextSetWeak;
+ nextWeakSet = (WeakReference?)currentBucketSet.nextSetWeak;
if (nextWeakSet != null)
{
- nextBucketSet = (BucketSet)nextWeakSet.Target;
+ nextBucketSet = (BucketSet?)nextWeakSet.Target;
}
if (nextBucketSet == null)
{
do
{
- nextWeakSet = (WeakReference)currentBucketSet.nextSetWeak;
+ nextWeakSet = (WeakReference?)currentBucketSet.nextSetWeak;
if (nextWeakSet == null)
{
// Nothing more to do.
return;
}
- nextBucketSet = (BucketSet)nextWeakSet.Target;
+ nextBucketSet = (BucketSet?)nextWeakSet.Target;
if (nextBucketSet == null)
{
// Again nothing more to do.
// expires, the thread will walk the list again, find the appropriate BucketSet to pinch off, and
// then time out the transactions. This means that it is possible for a transaction to live a bit longer,
// but not much.
- WeakReference abortingSetsWeak =
- (WeakReference)Interlocked.CompareExchange(ref lastBucketSet.nextSetWeak, null, nextWeakSet);
+ WeakReference? abortingSetsWeak =
+ (WeakReference?)Interlocked.CompareExchange(ref lastBucketSet.nextSetWeak, null, nextWeakSet);
if (abortingSetsWeak == nextWeakSet)
{
// Yea - now proceed to abort the transactions.
- BucketSet abortingBucketSets = null;
+ BucketSet? abortingBucketSets = null;
do
{
if (abortingSetsWeak != null)
{
- abortingBucketSets = (BucketSet)abortingSetsWeak.Target;
+ abortingBucketSets = (BucketSet?)abortingSetsWeak.Target;
}
else
{
if (abortingBucketSets != null)
{
abortingBucketSets.TimeoutTransactions();
- abortingSetsWeak = (WeakReference)abortingBucketSets.nextSetWeak;
+ abortingSetsWeak = (WeakReference?)abortingBucketSets.nextSetWeak;
}
}
while (abortingBucketSets != null);
internal class BucketSet
{
// Buckets are kept in sets. Each element of a set will have the same absoluteTimeout.
- internal object nextSetWeak;
- internal BucketSet prevSet;
+ internal object? nextSetWeak;
+ internal BucketSet? prevSet;
private readonly TransactionTable _table;
internal void TimeoutTransactions()
{
- Bucket currentBucket = headBucket;
+ Bucket? currentBucket = headBucket;
// It will always have a head.
do
{
currentBucket.TimeoutTransactions();
- WeakReference nextWeakBucket = (WeakReference)currentBucket.nextBucketWeak;
+ WeakReference? nextWeakBucket = (WeakReference?)currentBucket.nextBucketWeak;
if (nextWeakBucket != null)
{
- currentBucket = (Bucket)nextWeakBucket.Target;
+ currentBucket = (Bucket?)nextWeakBucket.Target;
}
else
{
private bool _timedOut;
private int _index;
private readonly int _size;
- private readonly InternalTransaction[] _transactions;
- internal WeakReference nextBucketWeak;
- private Bucket _previous;
+ private readonly InternalTransaction?[] _transactions;
+ internal WeakReference? nextBucketWeak;
+ private Bucket? _previous;
private readonly BucketSet _owningSet;
{
lock (tx)
{
- tx.State.Timeout(tx);
+ tx.State!.Timeout(tx);
}
}
}
for (i = 0; i <= transactionCount && i < _size; i++)
{
Debug.Assert(transactionCount == _index, "Index changed timing out transactions");
- InternalTransaction tx = _transactions[i];
+ InternalTransaction? tx = _transactions[i];
if (tx != null)
{
lock (tx)
{
- tx.State.Timeout(tx);
+ tx.State!.Timeout(tx);
}
}
}
public override int GetHashCode() => base.GetHashCode(); // Don't have anything better to do.
- public override bool Equals(object obj) => obj is TransactionTraceIdentifier && Equals((TransactionTraceIdentifier)obj);
+ public override bool Equals(object? obj) => obj is TransactionTraceIdentifier transactionTraceId && Equals(transactionTraceId);
public bool Equals(TransactionTraceIdentifier other) =>
_cloneIdentifier == other._cloneIdentifier &&
// Transactions Events
//
[NonEvent]
- public static string IdOf(object value) => value != null ? value.GetType().Name + "#" + GetHashCode(value) : NullInstance;
+ public static string IdOf(object? value) => value != null ? value.GetType().Name + "#" + GetHashCode(value) : NullInstance;
[NonEvent]
- public static int GetHashCode(object value) => value?.GetHashCode() ?? 0;
+ public static int GetHashCode(object? value) => value?.GetHashCode() ?? 0;
#region Transaction Creation
/// <summary>Trace an event when a new transaction is created.</summary>
/// <param name="transaction">The transaction that was created.</param>
/// <param name="type">The type of transaction.</param>Method
[NonEvent]
- internal void TransactionCreated(Transaction transaction, string type)
+ internal void TransactionCreated(Transaction transaction, string? type)
{
Debug.Assert(transaction != null, "Transaction needed for the ETW event.");
}
[Event(TRANSACTION_CREATED_EVENTID, Keywords = Keywords.TraceLtm, Level = EventLevel.Informational, Task = Tasks.Transaction, Opcode = Opcodes.Create, Message = "Transaction Created. ID is {0}, type is {1}")]
- private void TransactionCreated(string transactionIdentifier, string type)
+ private void TransactionCreated(string transactionIdentifier, string? type)
{
SetActivityId(transactionIdentifier);
WriteEvent(TRANSACTION_CREATED_EVENTID, transactionIdentifier, type);
/// <param name="message">The message for the exception.</param>
/// <param name="innerExceptionStr">The inner exception.</param>
[NonEvent]
- internal void TransactionExceptionTrace(TraceSourceType traceSource, TransactionExceptionType type, string message, string innerExceptionStr)
+ internal void TransactionExceptionTrace(TraceSourceType traceSource, TransactionExceptionType type, string? message, string? innerExceptionStr)
{
if (IsEnabled(EventLevel.Error, ALL_KEYWORDS))
{
/// <param name="message">The message for the exception.</param>
/// <param name="innerExceptionStr">The inner exception.</param>
[NonEvent]
- internal void TransactionExceptionTrace(TransactionExceptionType type, string message, string innerExceptionStr)
+ internal void TransactionExceptionTrace(TransactionExceptionType type, string? message, string? innerExceptionStr)
{
if (IsEnabled(EventLevel.Error, ALL_KEYWORDS))
{
}
[Event(TRANSACTION_EXCEPTION_BASE_EVENTID, Keywords = Keywords.TraceBase, Level = EventLevel.Error, Task = Tasks.TransactionException, Message = "Transaction Exception. Type is {0}, message is {1}, InnerException is {2}")]
- private void TransactionExceptionBase(string type, string message, string innerExceptionStr)
+ private void TransactionExceptionBase(string? type, string? message, string? innerExceptionStr)
{
SetActivityId(string.Empty);
WriteEvent(TRANSACTION_EXCEPTION_BASE_EVENTID, type, message, innerExceptionStr);
}
[Event(TRANSACTION_EXCEPTION_LTM_EVENTID, Keywords = Keywords.TraceLtm, Level = EventLevel.Error, Task = Tasks.TransactionException, Message = "Transaction Exception. Type is {0}, message is {1}, InnerException is {2}")]
- private void TransactionExceptionLtm(string type, string message, string innerExceptionStr)
+ private void TransactionExceptionLtm(string? type, string? message, string? innerExceptionStr)
{
SetActivityId(string.Empty);
WriteEvent(TRANSACTION_EXCEPTION_LTM_EVENTID, type, message, innerExceptionStr);
/// <param name="type">The type of transaction.</param>
/// <param name="operation">The operationont the transaction.</param>
[NonEvent]
- internal void InvalidOperation(string type, string operation)
+ internal void InvalidOperation(string? type, string? operation)
{
if (IsEnabled(EventLevel.Error, ALL_KEYWORDS))
{
}
}
[Event(TRANSACTION_INVALID_OPERATION_EVENTID, Keywords = Keywords.TraceBase, Level = EventLevel.Error, Task = Tasks.Transaction, Opcode = Opcodes.InvalidOperation, Message = "Transaction Invalid Operation. ID is {0}, type is {1} and operation is {2}")]
- private void TransactionInvalidOperation(string transactionIdentifier, string type, string operation)
+ private void TransactionInvalidOperation(string? transactionIdentifier, string? type, string? operation)
{
SetActivityId(string.Empty);
WriteEvent(TRANSACTION_INVALID_OPERATION_EVENTID, transactionIdentifier, type, operation);
/// <param name="transaction">The transaction to rollback.</param>
/// <param name="type">The type of transaction.</param>
[NonEvent]
- internal void TransactionRollback(Transaction transaction, string type)
+ internal void TransactionRollback(Transaction transaction, string? type)
{
Debug.Assert(transaction != null, "Transaction needed for the ETW event.");
}
[Event(TRANSACTION_ROLLBACK_EVENTID, Keywords = Keywords.TraceLtm, Level = EventLevel.Warning, Task = Tasks.Transaction, Opcode = Opcodes.Rollback, Message = "Transaction Rollback. ID is {0}, type is {1}")]
- private void TransactionRollback(string transactionIdentifier, string type)
+ private void TransactionRollback(string transactionIdentifier, string? type)
{
SetActivityId(transactionIdentifier);
WriteEvent(TRANSACTION_ROLLBACK_EVENTID, transactionIdentifier, type);
/// <param name="transaction">The transaction that do dependent clone.</param>
/// <param name="type">The type of transaction.</param>
[NonEvent]
- internal void TransactionDependentCloneComplete(Transaction transaction, string type)
+ internal void TransactionDependentCloneComplete(Transaction transaction, string? type)
{
Debug.Assert(transaction != null, "Transaction needed for the ETW event.");
}
[Event(TRANSACTION_DEPENDENT_CLONE_COMPLETE_EVENTID, Keywords = Keywords.TraceLtm, Level = EventLevel.Informational, Task = Tasks.Transaction, Opcode = Opcodes.DependentCloneComplete, Message = "Transaction Dependent Clone Completed. ID is {0}, type is {1}")]
- private void TransactionDependentCloneComplete(string transactionIdentifier, string type)
+ private void TransactionDependentCloneComplete(string transactionIdentifier, string? type)
{
SetActivityId(transactionIdentifier);
WriteEvent(TRANSACTION_DEPENDENT_CLONE_COMPLETE_EVENTID, transactionIdentifier, type);
/// <param name="transaction">The transaction to commit.</param>
/// <param name="type">The type of transaction.</param>
[NonEvent]
- internal void TransactionCommit(Transaction transaction, string type)
+ internal void TransactionCommit(Transaction transaction, string? type)
{
Debug.Assert(transaction != null, "Transaction needed for the ETW event.");
}
[Event(TRANSACTION_COMMIT_EVENTID, Keywords = Keywords.TraceLtm, Level = EventLevel.Verbose, Task = Tasks.Transaction, Opcode = Opcodes.Commit, Message = "Transaction Commit: ID is {0}, type is {1}")]
- private void TransactionCommit(string transactionIdentifier, string type)
+ private void TransactionCommit(string transactionIdentifier, string? type)
{
SetActivityId(transactionIdentifier);
WriteEvent(TRANSACTION_COMMIT_EVENTID, transactionIdentifier, type);
/// <param name="thisOrContextObject">'this', or another object that serves to provide context for the operation.</param>
/// <param name="methodname">The name of method.</param>
[NonEvent]
- internal void MethodEnter(TraceSourceType traceSource, object thisOrContextObject, [CallerMemberName] string methodname = null)
+ internal void MethodEnter(TraceSourceType traceSource, object? thisOrContextObject, [CallerMemberName] string? methodname = null)
{
if (IsEnabled(EventLevel.Verbose, ALL_KEYWORDS))
{
/// <param name="traceSource"> trace source</param>
/// <param name="methodname">The name of method.</param>
[NonEvent]
- internal void MethodEnter(TraceSourceType traceSource, [CallerMemberName] string methodname = null)
+ internal void MethodEnter(TraceSourceType traceSource, [CallerMemberName] string? methodname = null)
{
if (IsEnabled(EventLevel.Verbose, ALL_KEYWORDS))
{
}
[Event(METHOD_ENTER_LTM_EVENTID, Keywords = Keywords.TraceLtm, Level = EventLevel.Verbose, Task = Tasks.Method, Opcode = Opcodes.Enter, Message = "Enter method : {0}.{1}")]
- private void MethodEnterTraceLtm(string thisOrContextObject, string methodname)
+ private void MethodEnterTraceLtm(string thisOrContextObject, string? methodname)
{
SetActivityId(string.Empty);
WriteEvent(METHOD_ENTER_LTM_EVENTID, thisOrContextObject, methodname);
}
[Event(METHOD_ENTER_BASE_EVENTID, Keywords = Keywords.TraceBase, Level = EventLevel.Verbose, Task = Tasks.Method, Opcode = Opcodes.Enter, Message = "Enter method : {0}.{1}")]
- private void MethodEnterTraceBase(string thisOrContextObject, string methodname)
+ private void MethodEnterTraceBase(string thisOrContextObject, string? methodname)
{
SetActivityId(string.Empty);
WriteEvent(METHOD_ENTER_BASE_EVENTID, thisOrContextObject, methodname);
}
[Event(METHOD_ENTER_DISTRIBUTED_EVENTID, Keywords = Keywords.TraceDistributed, Level = EventLevel.Verbose, Task = Tasks.Method, Opcode = Opcodes.Enter, Message = "Enter method : {0}.{1}")]
- private void MethodEnterTraceDistributed(string thisOrContextObject, string methodname)
+ private void MethodEnterTraceDistributed(string thisOrContextObject, string? methodname)
{
SetActivityId(string.Empty);
WriteEvent(METHOD_ENTER_DISTRIBUTED_EVENTID, thisOrContextObject, methodname);
/// <param name="thisOrContextObject">'this', or another object that serves to provide context for the operation.</param>
/// <param name="methodname">The name of method.</param>
[NonEvent]
- internal void MethodExit(TraceSourceType traceSource, object thisOrContextObject, [CallerMemberName] string methodname = null)
+ internal void MethodExit(TraceSourceType traceSource, object? thisOrContextObject, [CallerMemberName] string? methodname = null)
{
if (IsEnabled(EventLevel.Verbose, ALL_KEYWORDS))
{
/// <param name="traceSource"> trace source</param>
/// <param name="methodname">The name of method.</param>
[NonEvent]
- internal void MethodExit(TraceSourceType traceSource, [CallerMemberName] string methodname = null)
+ internal void MethodExit(TraceSourceType traceSource, [CallerMemberName] string? methodname = null)
{
if (IsEnabled(EventLevel.Verbose, ALL_KEYWORDS))
{
}
[Event(METHOD_EXIT_LTM_EVENTID, Keywords = Keywords.TraceLtm, Level = EventLevel.Verbose, Task = Tasks.Method, Opcode = Opcodes.Exit, Message = "Exit method: {0}.{1}")]
- private void MethodExitTraceLtm(string thisOrContextObject, string methodname)
+ private void MethodExitTraceLtm(string thisOrContextObject, string? methodname)
{
SetActivityId(string.Empty);
WriteEvent(METHOD_EXIT_LTM_EVENTID, thisOrContextObject, methodname);
}
[Event(METHOD_EXIT_BASE_EVENTID, Keywords = Keywords.TraceBase, Level = EventLevel.Verbose, Task = Tasks.Method, Opcode = Opcodes.Exit, Message = "Exit method: {0}.{1}")]
- private void MethodExitTraceBase(string thisOrContextObject, string methodname)
+ private void MethodExitTraceBase(string thisOrContextObject, string? methodname)
{
SetActivityId(string.Empty);
WriteEvent(METHOD_EXIT_BASE_EVENTID, thisOrContextObject, methodname);
}
[Event(METHOD_EXIT_DISTRIBUTED_EVENTID, Keywords = Keywords.TraceDistributed, Level = EventLevel.Verbose, Task = Tasks.Method, Opcode = Opcodes.Exit, Message = "Exit method: {0}.{1}")]
- private void MethodExitTraceDistributed(string thisOrContextObject, string methodname)
+ private void MethodExitTraceDistributed(string thisOrContextObject, string? methodname)
{
SetActivityId(string.Empty);
WriteEvent(METHOD_EXIT_DISTRIBUTED_EVENTID, thisOrContextObject, methodname);
/// <summary>Trace an event when there is an internal error on transactionscope.</summary>
/// <param name="error">The error information.</param>
[NonEvent]
- internal void TransactionScopeInternalError(string error)
+ internal void TransactionScopeInternalError(string? error)
{
if (IsEnabled(EventLevel.Critical, ALL_KEYWORDS))
{
}
[Event(TRANSACTIONSCOPE_INTERNAL_ERROR_EVENTID, Keywords = Keywords.TraceBase, Level = EventLevel.Critical, Task = Tasks.TransactionScope, Opcode = Opcodes.InternalError, Message = "Transactionscope internal error: {0}")]
- private void TransactionScopeInternalErrorTrace(string error)
+ private void TransactionScopeInternalErrorTrace(string? error)
{
SetActivityId(string.Empty);
WriteEvent(TRANSACTIONSCOPE_INTERNAL_ERROR_EVENTID, error);
protected InternalTransaction _transaction;
// Store the IVolatileEnlistment interface to call back to the Distributed TM
- internal IPromotedEnlistment _promotedEnlistment;
- internal IPromotedEnlistment _preparingEnlistment;
+ internal IPromotedEnlistment? _promotedEnlistment;
+ internal IPromotedEnlistment? _preparingEnlistment;
public VolatileDemultiplexer(InternalTransaction transaction)
{
// Broadcast preprepare to the volatile subordinates
for (int i = 0; i < volatiles._volatileEnlistmentCount; i++)
{
- volatiles._volatileEnlistments[i]._twoPhaseState.InternalCommitted(
+ volatiles._volatileEnlistments[i]._twoPhaseState!.InternalCommitted(
volatiles._volatileEnlistments[i]);
}
}
// Broadcast preprepare to the volatile subordinates
for (int i = 0; i < volatiles._volatileEnlistmentCount; i++)
{
- volatiles._volatileEnlistments[i]._twoPhaseState.InternalAborted(
+ volatiles._volatileEnlistments[i]._twoPhaseState!.InternalAborted(
volatiles._volatileEnlistments[i]);
}
}
// Broadcast preprepare to the volatile subordinates
for (int i = 0; i < volatiles._volatileEnlistmentCount; i++)
{
- volatiles._volatileEnlistments[i]._twoPhaseState.InternalIndoubt(
+ volatiles._volatileEnlistments[i]._twoPhaseState!.InternalIndoubt(
volatiles._volatileEnlistments[i]);
}
}
// Object for synchronizing access to the entire class( avoiding lock( typeof( ... )) )
- private static object s_classSyncObject;
+ private static object? s_classSyncObject;
internal static object ClassSyncObject
{
get
}
}
- private static WaitCallback s_prepareCallback;
- private static WaitCallback PrepareCallback => LazyInitializer.EnsureInitialized(ref s_prepareCallback, ref s_classSyncObject, () => new WaitCallback(PoolablePrepare));
+ private static WaitCallback? s_prepareCallback;
+ private static WaitCallback PrepareCallback => LazyInitializer.EnsureInitialized(ref s_prepareCallback, ref s_classSyncObject, () => new WaitCallback(PoolablePrepare!));
protected static void PoolablePrepare(object state)
{
}
}
- private static WaitCallback s_commitCallback;
- private static WaitCallback CommitCallback => LazyInitializer.EnsureInitialized(ref s_commitCallback, ref s_classSyncObject, () => new WaitCallback(PoolableCommit));
+ private static WaitCallback? s_commitCallback;
+ private static WaitCallback CommitCallback => LazyInitializer.EnsureInitialized(ref s_commitCallback, ref s_classSyncObject, () => new WaitCallback(PoolableCommit!));
protected static void PoolableCommit(object state)
{
}
}
- private static WaitCallback s_rollbackCallback;
- private static WaitCallback RollbackCallback => LazyInitializer.EnsureInitialized(ref s_rollbackCallback, ref s_classSyncObject, () => new WaitCallback(PoolableRollback));
+ private static WaitCallback? s_rollbackCallback;
+ private static WaitCallback RollbackCallback => LazyInitializer.EnsureInitialized(ref s_rollbackCallback, ref s_classSyncObject, () => new WaitCallback(PoolableRollback!));
protected static void PoolableRollback(object state)
{
}
}
- private static WaitCallback s_inDoubtCallback;
- private static WaitCallback InDoubtCallback => LazyInitializer.EnsureInitialized(ref s_inDoubtCallback, ref s_classSyncObject, () => new WaitCallback(PoolableInDoubt));
+ private static WaitCallback? s_inDoubtCallback;
+ private static WaitCallback InDoubtCallback => LazyInitializer.EnsureInitialized(ref s_inDoubtCallback, ref s_classSyncObject, () => new WaitCallback(PoolableInDoubt!));
protected static void PoolableInDoubt(object state)
{
protected override void InternalPrepare()
{
+ Debug.Assert(_promotedEnlistment != null && _transaction.State != null);
try
{
_transaction.State.ChangeStatePromotedPhase0(_transaction);
protected override void InternalCommit()
{
+ Debug.Assert(_promotedEnlistment != null && _transaction.State != null);
+
// Respond immediately to the TM
_promotedEnlistment.EnlistmentDone();
protected override void InternalRollback()
{
+ Debug.Assert(_promotedEnlistment != null && _transaction.State != null);
+
// Respond immediately to the TM
_promotedEnlistment.EnlistmentDone();
protected override void InternalInDoubt()
{
+ Debug.Assert(_transaction.State != null);
_transaction.State.InDoubtFromDtc(_transaction);
}
protected override void InternalPrepare()
{
+ Debug.Assert(_promotedEnlistment != null && _transaction.State != null);
try
{
_transaction.State.ChangeStatePromotedPhase1(_transaction);
protected override void InternalCommit()
{
+ Debug.Assert(_promotedEnlistment != null && _transaction.State != null);
+
// Respond immediately to the TM
_promotedEnlistment.EnlistmentDone();
protected override void InternalRollback()
{
+ Debug.Assert(_promotedEnlistment != null && _transaction.State != null);
+
// Respond immediately to the TM
_promotedEnlistment.EnlistmentDone();
protected override void InternalInDoubt()
{
+ Debug.Assert(_transaction.State != null);
_transaction.State.InDoubtFromDtc(_transaction);
}
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Diagnostics;
using System.Threading;
namespace System.Transactions
// Base class for all volatile enlistment states
internal abstract class VolatileEnlistmentState : EnlistmentState
{
- private static VolatileEnlistmentActive s_volatileEnlistmentActive;
- private static VolatileEnlistmentPreparing s_volatileEnlistmentPreparing;
- private static VolatileEnlistmentPrepared s_volatileEnlistmentPrepared;
- private static VolatileEnlistmentSPC s_volatileEnlistmentSPC;
- private static VolatileEnlistmentPreparingAborting s_volatileEnlistmentPreparingAborting;
- private static VolatileEnlistmentAborting s_volatileEnlistmentAborting;
- private static VolatileEnlistmentCommitting s_volatileEnlistmentCommitting;
- private static VolatileEnlistmentInDoubt s_volatileEnlistmentInDoubt;
- private static VolatileEnlistmentEnded s_volatileEnlistmentEnded;
- private static VolatileEnlistmentDone s_volatileEnlistmentDone;
+ private static VolatileEnlistmentActive? s_volatileEnlistmentActive;
+ private static VolatileEnlistmentPreparing? s_volatileEnlistmentPreparing;
+ private static VolatileEnlistmentPrepared? s_volatileEnlistmentPrepared;
+ private static VolatileEnlistmentSPC? s_volatileEnlistmentSPC;
+ private static VolatileEnlistmentPreparingAborting? s_volatileEnlistmentPreparingAborting;
+ private static VolatileEnlistmentAborting? s_volatileEnlistmentAborting;
+ private static VolatileEnlistmentCommitting? s_volatileEnlistmentCommitting;
+ private static VolatileEnlistmentInDoubt? s_volatileEnlistmentInDoubt;
+ private static VolatileEnlistmentEnded? s_volatileEnlistmentEnded;
+ private static VolatileEnlistmentDone? s_volatileEnlistmentDone;
// Object for synchronizing access to the entire class( avoiding lock( typeof( ... )) )
- private static object s_classSyncObject;
+ private static object? s_classSyncObject;
internal static VolatileEnlistmentActive VolatileEnlistmentActive =>
LazyInitializer.EnsureInitialized(ref s_volatileEnlistmentActive, ref s_classSyncObject, () => new VolatileEnlistmentActive());
etwLog.EnlistmentStatus(enlistment, NotificationCall.Prepare);
}
+ Debug.Assert(enlistment.EnlistmentNotification != null);
enlistment.EnlistmentNotification.Prepare(enlistment.PreparingEnlistment);
}
finally
}
// The enlistment says to abort start the abort sequence.
- internal override void ForceRollback(InternalEnlistment enlistment, Exception e)
+ internal override void ForceRollback(InternalEnlistment enlistment, Exception? e)
{
// Change enlistment state to aborting
VolatileEnlistmentEnded.EnterState(enlistment);
+ Debug.Assert(enlistment.Transaction.State != null);
// Start the transaction aborting
enlistment.Transaction.State.ChangeStateTransactionAborted(enlistment.Transaction, e);
Monitor.Exit(enlistment.Transaction);
try // Don't hold this lock while calling into the application code.
{
+ Debug.Assert(enlistment.SinglePhaseNotification != null);
enlistment.SinglePhaseNotification.SinglePhaseCommit(enlistment.SinglePhaseEnlistment);
spcCommitted = true;
}
internal override void EnlistmentDone(InternalEnlistment enlistment)
{
VolatileEnlistmentEnded.EnterState(enlistment);
+ Debug.Assert(enlistment.Transaction.State != null);
enlistment.Transaction.State.ChangeStateTransactionCommitted(enlistment.Transaction);
}
internal override void Committed(InternalEnlistment enlistment)
{
VolatileEnlistmentEnded.EnterState(enlistment);
+ Debug.Assert(enlistment.Transaction.State != null);
enlistment.Transaction.State.ChangeStateTransactionCommitted(enlistment.Transaction);
}
- internal override void Aborted(InternalEnlistment enlistment, Exception e)
+ internal override void Aborted(InternalEnlistment enlistment, Exception? e)
{
VolatileEnlistmentEnded.EnterState(enlistment);
+ Debug.Assert(enlistment.Transaction.State != null);
enlistment.Transaction.State.ChangeStateTransactionAborted(enlistment.Transaction, e);
}
- internal override void InDoubt(InternalEnlistment enlistment, Exception e)
+ internal override void InDoubt(InternalEnlistment enlistment, Exception? e)
{
VolatileEnlistmentEnded.EnterState(enlistment);
enlistment.Transaction._innerException = e;
}
+ Debug.Assert(enlistment.Transaction.State != null);
enlistment.Transaction.State.InDoubtFromEnlistment(enlistment.Transaction);
}
}
}
// The enlistment says to abort start the abort sequence.
- internal override void ForceRollback(InternalEnlistment enlistment, Exception e)
+ internal override void ForceRollback(InternalEnlistment enlistment, Exception? e)
{
// Change enlistment state to aborting
VolatileEnlistmentEnded.EnterState(enlistment);
etwLog.EnlistmentStatus(enlistment, NotificationCall.Rollback);
}
+ Debug.Assert(enlistment.EnlistmentNotification != null);
enlistment.EnlistmentNotification.Rollback(enlistment.SinglePhaseEnlistment);
}
finally
etwLog.EnlistmentStatus(enlistment, NotificationCall.Commit);
}
+ Debug.Assert(enlistment.EnlistmentNotification != null);
// Forward the notification to the enlistment
enlistment.EnlistmentNotification.Commit(enlistment.Enlistment);
}
etwLog.EnlistmentStatus(enlistment, NotificationCall.InDoubt);
}
+ Debug.Assert(enlistment.EnlistmentNotification != null);
// Forward the notification to the enlistment
enlistment.EnlistmentNotification.InDoubt(enlistment.PreparingEnlistment);
}
// the transaction tells it to do so
}
- internal override void InDoubt(InternalEnlistment enlistment, Exception e)
+ internal override void InDoubt(InternalEnlistment enlistment, Exception? e)
{
// Ignore this in case the enlistment gets here before
// the transaction tells it to do so