Skip to content

Commit 276d494

Browse files
NH-2176 naming fix, clean up.
1 parent 419d434 commit 276d494

File tree

1 file changed

+21
-26
lines changed

1 file changed

+21
-26
lines changed

src/NHibernate/Transaction/AdoNetWithSystemTransactionFactory.cs

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,16 @@ public void EnlistInSystemTransactionIfNeeded(ISessionImplementor session)
3333
// Ensure the session does not run on a thread supposed to be blocked, waiting
3434
// for transaction completion.
3535
session.TransactionContext?.WaitOne();
36-
36+
3737
var transaction = System.Transactions.Transaction.Current;
38-
// We may have defined the transaction context before having the connection, do not
39-
// move under test on TransactionContext already defined. Otherwise we would rely on
40-
// connection auto-enlistment setting.
41-
session.ConnectionManager.EnlistIfRequired(transaction);
38+
// We may have defined the transaction context before having the connection, so we
39+
// need to ensure enlistment even when the transaction context is already defined.
40+
// But avoid redefining to a sub-scope transaction.
41+
if (session.TransactionContext == null ||
42+
((SystemTransactionContext)session.TransactionContext).AmbientTransaction == transaction)
43+
{
44+
session.ConnectionManager.EnlistIfRequired(transaction);
45+
}
4246

4347
if (session.TransactionContext != null || transaction == null)
4448
{
@@ -49,11 +53,11 @@ public void EnlistInSystemTransactionIfNeeded(ISessionImplementor session)
4953
session.TransactionContext = transactionContext;
5054
_logger.DebugFormat(
5155
"enlisted into DTC transaction: {0}",
52-
transactionContext.AmbientTransation.IsolationLevel);
56+
transactionContext.AmbientTransaction.IsolationLevel);
5357
session.AfterTransactionBegin(null);
5458

55-
transactionContext.AmbientTransation.TransactionCompleted += transactionContext.TransactionCompleted;
56-
transactionContext.AmbientTransation.EnlistVolatile(
59+
transactionContext.AmbientTransaction.TransactionCompleted += transactionContext.TransactionCompleted;
60+
transactionContext.AmbientTransaction.EnlistVolatile(
5761
transactionContext,
5862
EnlistmentOptions.EnlistDuringPrepareRequired);
5963
}
@@ -74,30 +78,30 @@ public void ExecuteWorkInIsolation(ISessionImplementor session, IIsolatedWork wo
7478

7579
public class SystemTransactionContext : ITransactionContext, IEnlistmentNotification
7680
{
77-
internal System.Transactions.Transaction AmbientTransation { get; private set; }
81+
internal System.Transactions.Transaction AmbientTransaction { get; private set; }
7882
public bool ShouldCloseSessionOnSystemTransactionCompleted { get; set; }
7983
public bool IsInActiveTransaction { get; internal set; }
8084

8185
private readonly ISessionImplementor _sessionImplementor;
8286
private readonly ManualResetEvent _waitEvent = new ManualResetEvent(true);
8387
private volatile bool _locked;
8488
private readonly AsyncLocal<bool> _bypassWait = new AsyncLocal<bool>();
85-
private bool IsDistributed => AmbientTransation.TransactionInformation.DistributedIdentifier != Guid.Empty;
89+
private bool IsDistributed => AmbientTransaction.TransactionInformation.DistributedIdentifier != Guid.Empty;
8690

8791
public SystemTransactionContext(
8892
ISessionImplementor sessionImplementor,
8993
System.Transactions.Transaction transaction)
9094
{
9195
_sessionImplementor = sessionImplementor;
92-
AmbientTransation = transaction.Clone();
96+
AmbientTransaction = transaction.Clone();
9397
IsInActiveTransaction = true;
9498
}
9599

96100
public void WaitOne()
97101
{
98102
if (_bypassWait.Value || _isDisposed)
99103
return;
100-
if (!_locked && AmbientTransation.TransactionInformation.Status != TransactionStatus.Active)
104+
if (!_locked && AmbientTransaction.TransactionInformation.Status != TransactionStatus.Active)
101105
// Rollback case may end the transaction without a prepare phase, apply the lock.
102106
SafeLockSession();
103107
try
@@ -157,7 +161,7 @@ void IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment)
157161
{
158162
try
159163
{
160-
using (var tx = new TransactionScope(AmbientTransation))
164+
using (var tx = new TransactionScope(AmbientTransaction))
161165
{
162166
if (_sessionImplementor.FlushMode != FlushMode.Manual && _sessionImplementor.ConnectionManager.IsConnected)
163167
{
@@ -197,9 +201,6 @@ void IEnlistmentNotification.InDoubt(Enlistment enlistment)
197201

198202
private void ProcessSecondPhase(Enlistment enlistment, bool? success)
199203
{
200-
// In case of rollback, the prepare phase may have not be run, and we then need to lock as soon as possible.
201-
// There is no guarantee the second phase will be run before the completed event, doing that at both places.
202-
SafeLockSession();
203204
using (new SessionIdLoggingContext(_sessionImplementor.SessionId))
204205
{
205206
_logger.Debug(
@@ -225,9 +226,6 @@ private void ProcessSecondPhase(Enlistment enlistment, bool? success)
225226

226227
public void TransactionCompleted(object sender, TransactionEventArgs e)
227228
{
228-
// In case of rollback, the prepare phase may have not be run, and we then need to lock as soon as possible.
229-
// There is no guarantee the second phase will be run before the completed event, doing that at both places.
230-
SafeLockSession();
231229
e.Transaction.TransactionCompleted -= TransactionCompleted;
232230
// This event may execute before second phase, so we cannot try to get the success from second phase.
233231
// Using this event is required by example in case the prepare phase failed and called force rollback:
@@ -237,7 +235,7 @@ public void TransactionCompleted(object sender, TransactionEventArgs e)
237235
try
238236
{
239237
wasSuccessful =
240-
e.Transaction.TransactionInformation.Status == TransactionStatus.Committed;
238+
AmbientTransaction.TransactionInformation.Status == TransactionStatus.Committed;
241239
}
242240
catch (ObjectDisposedException ode)
243241
{
@@ -253,6 +251,7 @@ private void RunAfterTransactionActions(bool wasSuccessful)
253251
if (_afterTransactionActionsDone)
254252
// Probably called from In-Doubt and TransactionCompleted.
255253
return;
254+
_afterTransactionActionsDone = true;
256255
// Allow transaction completed actions to run while others stay blocked.
257256
_bypassWait.Value = true;
258257
try
@@ -272,7 +271,6 @@ private void RunAfterTransactionActions(bool wasSuccessful)
272271
}
273272
finally
274273
{
275-
_afterTransactionActionsDone = true;
276274
// Dispose releases blocked threads by the way.
277275
// Must dispose in case !ShouldCloseSessionOnSystemTransactionCompleted, since
278276
// we nullify session TransactionContext, causing it to have nothing still holding it.
@@ -296,11 +294,8 @@ protected virtual void Dispose(bool disposing)
296294
{
297295
if (disposing)
298296
{
299-
if (AmbientTransation != null)
300-
{
301-
AmbientTransation.Dispose();
302-
AmbientTransation = null;
303-
}
297+
AmbientTransaction?.Dispose();
298+
AmbientTransaction = null;
304299
_waitEvent.Set();
305300
_waitEvent.Dispose();
306301
}

0 commit comments

Comments
 (0)