From 81ecb940d12b5ec9b9f1d388d8050801dd1a1c44 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Tue, 17 Aug 2021 15:59:38 -0700 Subject: [PATCH 1/3] Fix unknown transaction state issues --- .../Data/SqlClient/SqlDelegatedTransaction.cs | 17 +++++++++++++++-- .../Data/SqlClient/SqlDelegatedTransaction.cs | 17 +++++++++++++++-- 2 files changed, 30 insertions(+), 4 deletions(-) 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..6ec23eab73 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 @@ -208,9 +208,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 Transction 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 { 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 { From a96de7f8d31ecf5d9541f2394819500537b616f1 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 17 Sep 2021 10:43:47 -0700 Subject: [PATCH 2/3] Update src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs Co-authored-by: DavoudEshtehari <61173489+DavoudEshtehari@users.noreply.github.com> --- .../src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6ec23eab73..d2ae5d031c 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 @@ -212,7 +212,7 @@ public byte[] Promote() { try { - // Safely access Transction status - as it's possible Transaction is not in right state. + // Safely access Transaction status - as it's possible Transaction is not in right state. if (Transaction?.TransactionInformation?.Status != TransactionStatus.Aborted) { throw SQL.PromotionFailed(promoteException); From ae58ab2c6b0ca0b75ec33aa75acfd64e8e08ffbd Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 17 Sep 2021 12:01:55 -0700 Subject: [PATCH 3/3] Add missing logs --- .../src/Microsoft/Data/SqlClient/SqlDelegatedTransaction.cs | 6 ++++++ 1 file changed, 6 insertions(+) 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 d2ae5d031c..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(); } } @@ -367,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 @@ -375,6 +380,7 @@ public void SinglePhaseCommit(SinglePhaseEnlistment enlistment) catch (InvalidOperationException e) { commitException = e; + ADP.TraceExceptionWithoutRethrow(e); connection.DoomThisConnection(); } if (commitException != null)