1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System.Diagnostics; 6 using System.Threading; 7 8 namespace System.Transactions 9 { 10 // Base class for all enlistment states 11 internal abstract class EnlistmentState 12 { EnterState(InternalEnlistment enlistment)13 internal abstract void EnterState(InternalEnlistment enlistment); 14 15 internal static EnlistmentStatePromoted _enlistmentStatePromoted; 16 17 // Object for synchronizing access to the entire class( avoiding lock( typeof( ... )) ) 18 private static object s_classSyncObject; 19 20 internal static EnlistmentStatePromoted EnlistmentStatePromoted => 21 LazyInitializer.EnsureInitialized(ref _enlistmentStatePromoted, ref s_classSyncObject, () => new EnlistmentStatePromoted()); 22 EnlistmentDone(InternalEnlistment enlistment)23 internal virtual void EnlistmentDone(InternalEnlistment enlistment) 24 { 25 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 26 } 27 Prepared(InternalEnlistment enlistment)28 internal virtual void Prepared(InternalEnlistment enlistment) 29 { 30 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 31 } 32 ForceRollback(InternalEnlistment enlistment, Exception e)33 internal virtual void ForceRollback(InternalEnlistment enlistment, Exception e) 34 { 35 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 36 } 37 Committed(InternalEnlistment enlistment)38 internal virtual void Committed(InternalEnlistment enlistment) 39 { 40 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 41 } 42 Aborted(InternalEnlistment enlistment, Exception e)43 internal virtual void Aborted(InternalEnlistment enlistment, Exception e) 44 { 45 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 46 } 47 InDoubt(InternalEnlistment enlistment, Exception e)48 internal virtual void InDoubt(InternalEnlistment enlistment, Exception e) 49 { 50 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 51 } 52 RecoveryInformation(InternalEnlistment enlistment)53 internal virtual byte[] RecoveryInformation(InternalEnlistment enlistment) 54 { 55 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 56 } 57 InternalAborted(InternalEnlistment enlistment)58 internal virtual void InternalAborted(InternalEnlistment enlistment) 59 { 60 Debug.Assert(false, string.Format(null, "Invalid Event for InternalEnlistment State; Current State: {0}", GetType())); 61 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 62 } 63 InternalCommitted(InternalEnlistment enlistment)64 internal virtual void InternalCommitted(InternalEnlistment enlistment) 65 { 66 Debug.Assert(false, string.Format(null, "Invalid Event for InternalEnlistment State; Current State: {0}", GetType())); 67 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 68 } 69 InternalIndoubt(InternalEnlistment enlistment)70 internal virtual void InternalIndoubt(InternalEnlistment enlistment) 71 { 72 Debug.Assert(false, string.Format(null, "Invalid Event for InternalEnlistment State; Current State: {0}", GetType())); 73 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 74 } 75 ChangeStateCommitting(InternalEnlistment enlistment)76 internal virtual void ChangeStateCommitting(InternalEnlistment enlistment) 77 { 78 Debug.Assert(false, string.Format(null, "Invalid Event for InternalEnlistment State; Current State: {0}", GetType())); 79 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 80 } 81 ChangeStatePromoted(InternalEnlistment enlistment, IPromotedEnlistment promotedEnlistment)82 internal virtual void ChangeStatePromoted(InternalEnlistment enlistment, IPromotedEnlistment promotedEnlistment) 83 { 84 Debug.Assert(false, string.Format(null, "Invalid Event for InternalEnlistment State; Current State: {0}", GetType())); 85 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 86 } 87 ChangeStateDelegated(InternalEnlistment enlistment)88 internal virtual void ChangeStateDelegated(InternalEnlistment enlistment) 89 { 90 Debug.Assert(false, string.Format(null, "Invalid Event for InternalEnlistment State; Current State: {0}", GetType())); 91 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 92 } 93 ChangeStatePreparing(InternalEnlistment enlistment)94 internal virtual void ChangeStatePreparing(InternalEnlistment enlistment) 95 { 96 Debug.Assert(false, string.Format(null, "Invalid Event for InternalEnlistment State; Current State: {0}", GetType())); 97 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 98 } 99 ChangeStateSinglePhaseCommit(InternalEnlistment enlistment)100 internal virtual void ChangeStateSinglePhaseCommit(InternalEnlistment enlistment) 101 { 102 Debug.Assert(false, string.Format(null, "Invalid Event for InternalEnlistment State; Current State: {0}", GetType())); 103 throw TransactionException.CreateEnlistmentStateException(null, enlistment == null ? Guid.Empty : enlistment.DistributedTxId); 104 } 105 } 106 107 internal class EnlistmentStatePromoted : EnlistmentState 108 { EnterState(InternalEnlistment enlistment)109 internal override void EnterState(InternalEnlistment enlistment) 110 { 111 enlistment.State = this; 112 } 113 EnlistmentDone(InternalEnlistment enlistment)114 internal override void EnlistmentDone(InternalEnlistment enlistment) 115 { 116 Monitor.Exit(enlistment.SyncRoot); 117 try 118 { 119 enlistment.PromotedEnlistment.EnlistmentDone(); 120 } 121 finally 122 { 123 Monitor.Enter(enlistment.SyncRoot); 124 } 125 } 126 Prepared(InternalEnlistment enlistment)127 internal override void Prepared(InternalEnlistment enlistment) 128 { 129 Monitor.Exit(enlistment.SyncRoot); 130 try 131 { 132 enlistment.PromotedEnlistment.Prepared(); 133 } 134 finally 135 { 136 Monitor.Enter(enlistment.SyncRoot); 137 } 138 } 139 ForceRollback(InternalEnlistment enlistment, Exception e)140 internal override void ForceRollback(InternalEnlistment enlistment, Exception e) 141 { 142 Monitor.Exit(enlistment.SyncRoot); 143 try 144 { 145 enlistment.PromotedEnlistment.ForceRollback(e); 146 } 147 finally 148 { 149 Monitor.Enter(enlistment.SyncRoot); 150 } 151 } 152 Committed(InternalEnlistment enlistment)153 internal override void Committed(InternalEnlistment enlistment) 154 { 155 Monitor.Exit(enlistment.SyncRoot); 156 try 157 { 158 enlistment.PromotedEnlistment.Committed(); 159 } 160 finally 161 { 162 Monitor.Enter(enlistment.SyncRoot); 163 } 164 } 165 Aborted(InternalEnlistment enlistment, Exception e)166 internal override void Aborted(InternalEnlistment enlistment, Exception e) 167 { 168 Monitor.Exit(enlistment.SyncRoot); 169 try 170 { 171 enlistment.PromotedEnlistment.Aborted(e); 172 } 173 finally 174 { 175 Monitor.Enter(enlistment.SyncRoot); 176 } 177 } 178 InDoubt(InternalEnlistment enlistment, Exception e)179 internal override void InDoubt(InternalEnlistment enlistment, Exception e) 180 { 181 Monitor.Exit(enlistment.SyncRoot); 182 try 183 { 184 enlistment.PromotedEnlistment.InDoubt(e); 185 } 186 finally 187 { 188 Monitor.Enter(enlistment.SyncRoot); 189 } 190 } 191 RecoveryInformation(InternalEnlistment enlistment)192 internal override byte[] RecoveryInformation(InternalEnlistment enlistment) 193 { 194 Monitor.Exit(enlistment.SyncRoot); 195 try 196 { 197 return enlistment.PromotedEnlistment.GetRecoveryInformation(); 198 } 199 finally 200 { 201 Monitor.Enter(enlistment.SyncRoot); 202 } 203 } 204 } 205 } 206