diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs index 714c13d54c..5ca53cfa3a 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalTransaction.cs @@ -219,15 +219,6 @@ internal void Activate() _transactionState = TransactionState.Active; } - private void DoomConnectionNoReuse(SqlInternalConnection innerConnection) - { - if (null != innerConnection) - { - innerConnection.DoNotPoolThisConnection(); - innerConnection.DoomThisConnection(); - } - } - private void CheckTransactionLevelAndZombie() { try @@ -298,11 +289,6 @@ internal void Commit() } catch (Exception e) { - // GitHub Issue #130 - When an exception has occurred on transaction completion request, - // this connection may not be in reusable state. - // We will doom this connection and make sure it does not go back to the pool. - DoomConnectionNoReuse(_innerConnection); - if (ADP.IsCatchableExceptionType(e)) { CheckTransactionLevelAndZombie(); diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlTransaction.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlTransaction.cs index eb32a81df7..14c9f3081f 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlTransaction.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlTransaction.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.ComponentModel; using System.Data; using System.Data.Common; using System.Diagnostics; @@ -140,6 +141,19 @@ override public void Commit() _internalTransaction.Commit(); } + catch (SqlException ex) + { + // GitHub Issue #130 - When a timeout exception has occurred on transaction completion request, + // this connection may not be in reusable state. + // We will abort this connection and make sure it does not go back to the pool. + var innerException = ex.InnerException as Win32Exception; + if (innerException != null && innerException.NativeErrorCode == TdsEnums.SNI_WAIT_TIMEOUT) + { + _connection.Abort(ex); + } + e = ex; + throw; + } catch (Exception ex) { e = ex; diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlTransaction.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlTransaction.cs index 235ac7651d..53e195ad77 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlTransaction.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlTransaction.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.ComponentModel; using System.Data; using System.Data.Common; using System.Diagnostics; @@ -188,6 +189,18 @@ override public void Commit() SqlInternalConnection.BestEffortCleanup(bestEffortCleanupTarget); throw; } + catch (SqlException e) + { + // GitHub Issue #130 - When a timeout exception has occurred on transaction completion request, + // this connection may not be in reusable state. + // We will abort this connection and make sure it does not go back to the pool. + var innerException = e.InnerException as Win32Exception; + if (innerException != null && innerException.NativeErrorCode == TdsEnums.SNI_WAIT_TIMEOUT) + { + _connection.Abort(e); + } + throw; + } finally { _isFromAPI = false; diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/sqlinternaltransaction.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/sqlinternaltransaction.cs index 28b9cb82b8..540b4294e0 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/sqlinternaltransaction.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/sqlinternaltransaction.cs @@ -244,15 +244,6 @@ internal void Activate() _transactionState = TransactionState.Active; } - private void DoomConnectionNoReuse(SqlInternalConnection innerConnection) - { - if (null != innerConnection) - { - innerConnection.DoNotPoolThisConnection(); - innerConnection.DoomThisConnection(); - } - } - private void CheckTransactionLevelAndZombie() { try @@ -344,11 +335,6 @@ internal void Commit() } catch (Exception e) { - // GitHub Issue #130 - When an exception has occurred on transaction completion request, - // this connection may not be in reusable state. - // We will doom this connection and make sure it does not go back to the pool. - DoomConnectionNoReuse(_innerConnection); - // UNDONE - should not be catching all exceptions!!! if (ADP.IsCatchableExceptionType(e)) {