diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
index cffb127ec7..9e1df81f9c 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -256,6 +256,9 @@
Microsoft\Data\SqlClient\Server\SqlRecordBuffer.cs
+
+ Microsoft\Data\SqlClient\SqlTransaction.Common.cs
+
Microsoft\Data\SqlClient\Server\SqlUserDefinedAggregateAttribute.cs
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 2eecfdc8cc..1c3df017dd 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
@@ -4,136 +4,22 @@
using System;
using System.ComponentModel;
-using System.Data;
using System.Data.Common;
-using System.Diagnostics;
using Microsoft.Data.Common;
namespace Microsoft.Data.SqlClient
{
///
- public sealed class SqlTransaction : DbTransaction
+ public sealed partial class SqlTransaction : DbTransaction
{
- private static readonly SqlDiagnosticListener s_diagnosticListener = new SqlDiagnosticListener(SqlClientDiagnosticListenerExtensions.DiagnosticListenerName);
- private static int _objectTypeCount; // EventSource Counter
- internal readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount);
- internal readonly IsolationLevel _isolationLevel = IsolationLevel.ReadCommitted;
-
- private SqlInternalTransaction _internalTransaction;
- private SqlConnection _connection;
-
- private bool _isFromAPI;
-
- internal SqlTransaction(SqlInternalConnection internalConnection, SqlConnection con,
- IsolationLevel iso, SqlInternalTransaction internalTransaction)
- {
- _isolationLevel = iso;
- _connection = con;
-
- if (internalTransaction == null)
- {
- _internalTransaction = new SqlInternalTransaction(internalConnection, TransactionType.LocalFromAPI, this);
- }
- else
- {
- Debug.Assert(internalConnection.CurrentTransaction == internalTransaction, "Unexpected Parser.CurrentTransaction state!");
- _internalTransaction = internalTransaction;
- _internalTransaction.InitParent(this);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // PROPERTIES
- ////////////////////////////////////////////////////////////////////////////////////////
-
- ///
- new public SqlConnection Connection
- {
- get
- {
- if (IsZombied)
- {
- return null;
- }
- else
- {
- return _connection;
- }
- }
- }
-
- ///
- override protected DbConnection DbConnection
- {
- get
- {
- return Connection;
- }
- }
-
- internal SqlInternalTransaction InternalTransaction
- {
- get
- {
- return _internalTransaction;
- }
- }
-
- ///
- override public IsolationLevel IsolationLevel
- {
- get
- {
- ZombieCheck();
- return _isolationLevel;
- }
- }
-
- private bool Is2005PartialZombie
- {
- get
- {
- return (null != _internalTransaction && _internalTransaction.IsCompleted);
- }
- }
-
- internal bool IsZombied
- {
- get
- {
- return (null == _internalTransaction || _internalTransaction.IsCompleted);
- }
- }
-
- internal int ObjectID
- {
- get
- {
- return _objectID;
- }
- }
-
- internal SqlStatistics Statistics
- {
- get
- {
- if (null != _connection)
- {
- if (_connection.StatisticsEnabled)
- {
- return _connection.Statistics;
- }
- }
- return null;
- }
- }
+ private static readonly SqlDiagnosticListener s_diagnosticListener = new(SqlClientDiagnosticListenerExtensions.DiagnosticListenerName);
////////////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
////////////////////////////////////////////////////////////////////////////////////////
///
- override public void Commit()
+ public override void Commit()
{
using (DiagnosticTransactionScope diagnosticScope = s_diagnosticListener.CreateTransactionCommitScope(_isolationLevel, _connection, InternalTransaction))
{
@@ -191,7 +77,7 @@ protected override void Dispose(bool disposing)
}
///
- override public void Rollback()
+ public override void Rollback()
{
using (DiagnosticTransactionScope diagnosticScope = s_diagnosticListener.CreateTransactionRollbackScope(_isolationLevel, _connection, InternalTransaction, null))
{
@@ -284,45 +170,5 @@ public void Save(string savePointName)
}
}
}
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // INTERNAL METHODS
- ////////////////////////////////////////////////////////////////////////////////////////
-
- internal void Zombie()
- {
- // For 2005, we have to defer "zombification" until
- // we get past the users' next rollback, else we'll
- // throw an exception there that is a breaking change.
- // Of course, if the connection is already closed,
- // then we're free to zombify...
- SqlInternalConnection internalConnection = (_connection.InnerConnection as SqlInternalConnection);
- if (null != internalConnection && !_isFromAPI)
- {
- SqlClientEventSource.Log.TryAdvancedTraceEvent("SqlTransaction.Zombie | ADV | Object Id {0} 2005 deferred zombie", ObjectID);
- }
- else
- {
- _internalTransaction = null; // pre-2005 zombification
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // PRIVATE METHODS
- ////////////////////////////////////////////////////////////////////////////////////////
-
- private void ZombieCheck()
- {
- // If this transaction has been completed, throw exception since it is unusable.
- if (IsZombied)
- {
- if (Is2005PartialZombie)
- {
- _internalTransaction = null; // 2005 zombification
- }
-
- throw ADP.TransactionZombied(this);
- }
- }
}
}
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
index ab43046cb3..b659a27953 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
@@ -320,6 +320,9 @@
Microsoft\Data\SqlClient\Server\SqlRecordBuffer.cs
+
+ Microsoft\Data\SqlClient\SqlTransaction.Common.cs
+
Microsoft\Data\SqlClient\Server\ValueUtilsSmi.cs
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 6b10dc40ef..d5a93b1b86 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,139 +3,21 @@
// See the LICENSE file in the project root for more information.
using System.ComponentModel;
-using System.Data;
using System.Data.Common;
-using System.Diagnostics;
using System.Runtime.CompilerServices;
using Microsoft.Data.Common;
-
namespace Microsoft.Data.SqlClient
{
///
- public sealed class SqlTransaction : DbTransaction
+ public sealed partial class SqlTransaction : DbTransaction
{
- private static int _objectTypeCount; // EventSource Counter
- internal readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount);
- internal readonly IsolationLevel _isolationLevel = IsolationLevel.ReadCommitted;
-
- private SqlInternalTransaction _internalTransaction;
- private SqlConnection _connection;
-
- private bool _isFromAPI;
-
- internal SqlTransaction(SqlInternalConnection internalConnection, SqlConnection con,
- IsolationLevel iso, SqlInternalTransaction internalTransaction)
- {
- SqlConnection.VerifyExecutePermission();
-
- _isolationLevel = iso;
- _connection = con;
-
- if (internalTransaction == null)
- {
- _internalTransaction = new SqlInternalTransaction(internalConnection, TransactionType.LocalFromAPI, this);
- }
- else
- {
- Debug.Assert(internalConnection.CurrentTransaction == internalTransaction, "Unexpected Parser.CurrentTransaction state!");
- _internalTransaction = internalTransaction;
- _internalTransaction.InitParent(this);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // PROPERTIES
- ////////////////////////////////////////////////////////////////////////////////////////
-
- ///
- new public SqlConnection Connection
- { // MDAC 66655
- get
- {
- if (IsZombied)
- {
- return null;
- }
- else
- {
- return _connection;
- }
- }
- }
-
- ///
- override protected DbConnection DbConnection
- {
- get
- {
- return Connection;
- }
- }
-
- internal SqlInternalTransaction InternalTransaction
- {
- get
- {
- return _internalTransaction;
- }
- }
-
- ///
- override public IsolationLevel IsolationLevel
- {
- get
- {
- ZombieCheck();
- return _isolationLevel;
- }
- }
-
- private bool Is2005PartialZombie
- {
- get
- {
- return (null != _internalTransaction && _internalTransaction.IsCompleted);
- }
- }
-
- internal bool IsZombied
- {
- get
- {
- return (null == _internalTransaction || _internalTransaction.IsCompleted);
- }
- }
-
- internal int ObjectID
- {
- get
- {
- return _objectID;
- }
- }
-
- internal SqlStatistics Statistics
- {
- get
- {
- if (null != _connection)
- {
- if (_connection.StatisticsEnabled)
- {
- return _connection.Statistics;
- }
- }
- return null;
- }
- }
-
////////////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
////////////////////////////////////////////////////////////////////////////////////////
///
- override public void Commit()
+ public override void Commit()
{
SqlConnection.ExecutePermission.Demand(); // MDAC 81476
@@ -151,14 +33,14 @@ override public void Commit()
try
{
#if DEBUG
- TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();
+ TdsParser.ReliabilitySection tdsReliabilitySection = new();
RuntimeHelpers.PrepareConstrainedRegions();
try
{
tdsReliabilitySection.Start();
#else
- {
+ {
#endif //DEBUG
bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection);
statistics = SqlStatistics.StartTimer(Statistics);
@@ -195,8 +77,7 @@ override public void Commit()
// 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)
+ if (e.InnerException is Win32Exception innerException && innerException.NativeErrorCode == TdsEnums.SNI_WAIT_TIMEOUT)
{
_connection.Abort(e);
}
@@ -221,7 +102,7 @@ protected override void Dispose(bool disposing)
try
{
#if DEBUG
- TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();
+ TdsParser.ReliabilitySection tdsReliabilitySection = new();
RuntimeHelpers.PrepareConstrainedRegions();
try
@@ -264,7 +145,7 @@ protected override void Dispose(bool disposing)
}
///
- override public void Rollback()
+ public override void Rollback()
{
if (Is2005PartialZombie)
{
@@ -287,14 +168,14 @@ override public void Rollback()
try
{
#if DEBUG
- TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();
+ TdsParser.ReliabilitySection tdsReliabilitySection = new();
RuntimeHelpers.PrepareConstrainedRegions();
try
{
tdsReliabilitySection.Start();
#else
- {
+ {
#endif //DEBUG
bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection);
statistics = SqlStatistics.StartTimer(Statistics);
@@ -351,14 +232,14 @@ public void Rollback(string transactionName)
try
{
#if DEBUG
- TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();
+ TdsParser.ReliabilitySection tdsReliabilitySection = new();
RuntimeHelpers.PrepareConstrainedRegions();
try
{
tdsReliabilitySection.Start();
#else
- {
+ {
#endif //DEBUG
bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection);
statistics = SqlStatistics.StartTimer(Statistics);
@@ -415,14 +296,14 @@ public void Save(string savePointName)
try
{
#if DEBUG
- TdsParser.ReliabilitySection tdsReliabilitySection = new TdsParser.ReliabilitySection();
+ TdsParser.ReliabilitySection tdsReliabilitySection = new();
RuntimeHelpers.PrepareConstrainedRegions();
try
{
tdsReliabilitySection.Start();
#else
- {
+ {
#endif //DEBUG
bestEffortCleanupTarget = SqlInternalConnection.GetBestEffortCleanupTarget(_connection);
statistics = SqlStatistics.StartTimer(Statistics);
@@ -458,49 +339,5 @@ public void Save(string savePointName)
}
}
}
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // INTERNAL METHODS
- ////////////////////////////////////////////////////////////////////////////////////////
-
- internal void Zombie()
- {
- // SQLBUDT #402544 For 2005, we have to defer "zombification" until
- // we get past the users' next rollback, else we'll
- // throw an exception there that is a breaking change.
- // Of course, if the connection is aready closed,
- // then we're free to zombify...
- SqlInternalConnection internalConnection = (_connection.InnerConnection as SqlInternalConnection);
-
- if (null != internalConnection && internalConnection.Is2005OrNewer && !_isFromAPI)
- {
- SqlClientEventSource.Log.TryAdvancedTraceEvent(" {0} 2005 deferred zombie", ObjectID);
- }
- else
- {
- _internalTransaction = null; // pre-2005 zombification
- }
-
- }
-
- ////////////////////////////////////////////////////////////////////////////////////////
- // PRIVATE METHODS
- ////////////////////////////////////////////////////////////////////////////////////////
-
- private void ZombieCheck()
- {
- // If this transaction has been completed, throw exception since it is unusable.
- if (IsZombied)
- {
-
- if (Is2005PartialZombie)
- {
- _internalTransaction = null; // 2005 zombification
- }
-
- throw ADP.TransactionZombied(this);
- }
- }
}
}
-
diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.Common.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.Common.cs
new file mode 100644
index 0000000000..19996684b9
--- /dev/null
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlTransaction.Common.cs
@@ -0,0 +1,145 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Data;
+using System.Data.Common;
+using System.Diagnostics;
+using Microsoft.Data.Common;
+
+namespace Microsoft.Data.SqlClient
+{
+ ///
+ public sealed partial class SqlTransaction : DbTransaction
+ {
+ private static int s_objectTypeCount; // EventSource Counter
+ internal readonly int _objectID = System.Threading.Interlocked.Increment(ref s_objectTypeCount);
+ internal readonly IsolationLevel _isolationLevel = IsolationLevel.ReadCommitted;
+
+ private SqlInternalTransaction _internalTransaction;
+ private readonly SqlConnection _connection;
+
+ private bool _isFromAPI;
+
+ internal SqlTransaction(SqlInternalConnection internalConnection, SqlConnection con,
+ IsolationLevel iso, SqlInternalTransaction internalTransaction)
+ {
+#if NETFRAMEWORK
+ SqlConnection.VerifyExecutePermission();
+#endif
+ _isolationLevel = iso;
+ _connection = con;
+
+ if (internalTransaction == null)
+ {
+ _internalTransaction = new SqlInternalTransaction(internalConnection, TransactionType.LocalFromAPI, this);
+ }
+ else
+ {
+ Debug.Assert(internalConnection.CurrentTransaction == internalTransaction, "Unexpected Parser.CurrentTransaction state!");
+ _internalTransaction = internalTransaction;
+ _internalTransaction.InitParent(this);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // PROPERTIES
+ ////////////////////////////////////////////////////////////////////////////////////////
+
+ ///
+ public new SqlConnection Connection
+ {// MDAC 66655
+ get
+ {
+ if (IsZombied)
+ {
+ return null;
+ }
+ else
+ {
+ return _connection;
+ }
+ }
+ }
+
+ ///
+ protected override DbConnection DbConnection => Connection;
+
+ internal SqlInternalTransaction InternalTransaction => _internalTransaction;
+
+ ///
+ public override IsolationLevel IsolationLevel
+ {
+ get
+ {
+ ZombieCheck();
+ return _isolationLevel;
+ }
+ }
+
+ private bool Is2005PartialZombie => _internalTransaction !=null && _internalTransaction.IsCompleted;
+
+ internal bool IsZombied => _internalTransaction == null || _internalTransaction.IsCompleted;
+
+ internal int ObjectID => _objectID;
+
+ internal SqlStatistics Statistics
+ {
+ get
+ {
+ if (null != _connection)
+ {
+ if (_connection.StatisticsEnabled)
+ {
+ return _connection.Statistics;
+ }
+ }
+ return null;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // INTERNAL METHODS
+ ////////////////////////////////////////////////////////////////////////////////////////
+
+ internal void Zombie()
+ {
+ // For Yukon, we have to defer "zombification" until
+ // we get past the users' next rollback, else we'll
+ // throw an exception there that is a breaking change.
+ // Of course, if the connection is already closed,
+ // then we're free to zombify...
+ SqlInternalConnection internalConnection = (_connection.InnerConnection as SqlInternalConnection);
+ if (null != internalConnection
+#if NETFRAMEWORK
+ && internalConnection.Is2005OrNewer
+#endif
+ && !_isFromAPI)
+ {
+ SqlClientEventSource.Log.TryAdvancedTraceEvent("SqlTransaction.Zombie | ADV | Object Id {0} yukon deferred zombie", ObjectID);
+ }
+ else
+ {
+ _internalTransaction = null; // pre SQL 2005 zombification
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // PRIVATE METHODS
+ ////////////////////////////////////////////////////////////////////////////////////////
+
+ private void ZombieCheck()
+ {
+ // If this transaction has been completed, throw exception since it is unusable.
+ if (IsZombied)
+ {
+ if (Is2005PartialZombie)
+ {
+ _internalTransaction = null; // SQL 2005 zombification
+ }
+
+ throw ADP.TransactionZombied(this);
+ }
+ }
+ }
+}