diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs index e861c7ec31..3c289bb790 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs @@ -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 @@ -187,6 +189,7 @@ public byte[] Promote() catch (InvalidOperationException e) { promoteException = e; + ADP.TraceExceptionWithoutRethrow(e); connection.DoomThisConnection(); } } @@ -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 { @@ -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 @@ -362,6 +380,7 @@ public void SinglePhaseCommit(SinglePhaseEnlistment enlistment) catch (InvalidOperationException e) { commitException = e; + ADP.TraceExceptionWithoutRethrow(e); connection.DoomThisConnection(); } if (commitException != null) diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs index 7bf191e837..263f6618d8 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs @@ -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 {