Skip to content

Commit

Permalink
Fix unknown transaction state issues when promoting delegated transac…
Browse files Browse the repository at this point in the history
…tion (#1216)
  • Loading branch information
cheenamalhotra authored Sep 20, 2021
1 parent 5cd0f7d commit 186188d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ public byte[] Promote()
{
promoteException = e;

ADP.TraceExceptionWithoutRethrow(e);

// Doom the connection, to make sure that the transaction is
// eventually rolled back.
// VSTS 144562: doom the connection while having the lock on it to prevent race condition with "Transaction Ended" Event
Expand All @@ -187,6 +189,7 @@ public byte[] Promote()
catch (InvalidOperationException e)
{
promoteException = e;
ADP.TraceExceptionWithoutRethrow(e);
connection.DoomThisConnection();
}
}
Expand All @@ -208,9 +211,22 @@ public byte[] Promote()
}

//Throw exception only if Transaction is still active and not yet aborted.
if (promoteException != null && Transaction.TransactionInformation.Status != TransactionStatus.Aborted)
if (promoteException != null)
{
throw SQL.PromotionFailed(promoteException);
try
{
// Safely access Transaction status - as it's possible Transaction is not in right state.
if (Transaction?.TransactionInformation?.Status != TransactionStatus.Aborted)
{
throw SQL.PromotionFailed(promoteException);
}
}
catch (TransactionException te)
{
SqlClientEventSource.Log.TryTraceEvent("SqlDelegatedTransaction.Promote | RES | CPOOL | Object Id {0}, Client Connection Id {1}, Transaction exception occurred: {2}.", ObjectID, usersConnection?.ClientConnectionId, te.Message);
// Throw promote exception if transaction state is unknown.
throw SQL.PromotionFailed(promoteException);
}
}
else
{
Expand Down Expand Up @@ -354,6 +370,8 @@ public void SinglePhaseCommit(SinglePhaseEnlistment enlistment)
{
commitException = e;

ADP.TraceExceptionWithoutRethrow(e);

// Doom the connection, to make sure that the transaction is
// eventually rolled back.
// VSTS 144562: doom the connection while having the lock on it to prevent race condition with "Transaction Ended" Event
Expand All @@ -362,6 +380,7 @@ public void SinglePhaseCommit(SinglePhaseEnlistment enlistment)
catch (InvalidOperationException e)
{
commitException = e;
ADP.TraceExceptionWithoutRethrow(e);
connection.DoomThisConnection();
}
if (commitException != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,22 @@ public Byte[] Promote()
}

//Throw exception only if Transaction is still active and not yet aborted.
if (promoteException != null && Transaction.TransactionInformation.Status != SysTx.TransactionStatus.Aborted)
if (promoteException != null)
{
throw SQL.PromotionFailed(promoteException);
try
{
// Safely access Transction status - as it's possible Transaction is not in right state.
if(Transaction?.TransactionInformation?.Status == SysTx.TransactionStatus.Aborted)
{
throw SQL.PromotionFailed(promoteException);
}
}
catch(SysTx.TransactionException te)
{
SqlClientEventSource.Log.TryTraceEvent("SqlDelegatedTransaction.Promote | RES | CPOOL | Object Id {0}, Client Connection Id {1}, Transaction exception occurred: {2}.", ObjectID, usersConnection?.ClientConnectionId, te.Message);
// Throw promote exception if transaction state is unknown.
throw SQL.PromotionFailed(promoteException);
}
}
else
{
Expand Down

0 comments on commit 186188d

Please sign in to comment.