Skip to content

Commit 554fd2e

Browse files
Fix retry with SqlDataAdapter.Fill(SqlDataTable) on .NET Framework (#2084)
1 parent ed0c3a3 commit 554fd2e

File tree

2 files changed

+85
-17
lines changed

2 files changed

+85
-17
lines changed

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2409,8 +2409,8 @@ public IAsyncResult BeginExecuteReader(AsyncCallback callback, object stateObjec
24092409
/// <include file='../../../../../../../doc/snippets/Microsoft.Data.SqlClient/SqlCommand.xml' path='docs/members[@name="SqlCommand"]/ExecuteDbDataReader[@name="CommandBehavior"]/*'/>
24102410
protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
24112411
{
2412-
SqlClientEventSource.Log.TryCorrelationTraceEvent("<sc.SqlCommand.ExecuteDbDataReader|API|Correlation> ObjectID {0}, ActivityID {1}", ObjectID, ActivityCorrelator.Current);
2413-
return ExecuteReader(behavior, nameof(ExecuteReader));
2412+
SqlClientEventSource.Log.TryCorrelationTraceEvent("<sc.SqlCommand.ExecuteDbDataReader|API|Correlation> ObjectID {0}, ActivityID {1}, Client Connection Id {2}, Command Text '{3}'", ObjectID, ActivityCorrelator.Current, Connection?.ClientConnectionId, CommandText);
2413+
return ExecuteReader(behavior);
24142414
}
24152415

24162416
private SqlDataReader ExecuteReaderWithRetry(CommandBehavior behavior, string method)

src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AdapterTest/AdapterTest.cs

Lines changed: 83 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,22 +68,90 @@ public AdapterTest()
6868
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
6969
public void SimpleFillTest()
7070
{
71-
using (SqlConnection conn = new SqlConnection(DataTestUtility.TCPConnectionString))
72-
using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT EmployeeID, LastName, FirstName, Title, Address, City, Region, PostalCode, Country FROM Employees", conn))
71+
using SqlConnection conn = new(DataTestUtility.TCPConnectionString);
72+
using SqlDataAdapter adapter = new("SELECT EmployeeID, LastName, FirstName, Title, Address, City, Region, PostalCode, Country FROM Employees", conn);
73+
74+
DataSet employeesSet = new();
75+
DataTestUtility.AssertEqualsWithDescription(0, employeesSet.Tables.Count, "Unexpected tables count before fill.");
76+
adapter.Fill(employeesSet, "Employees");
77+
78+
DataTestUtility.AssertEqualsWithDescription(1, employeesSet.Tables.Count, "Unexpected tables count after fill.");
79+
DataTestUtility.AssertEqualsWithDescription("Employees", employeesSet.Tables[0].TableName, "Unexpected table name.");
80+
81+
DataTestUtility.AssertEqualsWithDescription(9, employeesSet.Tables["Employees"].Columns.Count, "Unexpected columns count.");
82+
employeesSet.Tables["Employees"].Columns.Remove("LastName");
83+
employeesSet.Tables["Employees"].Columns.Remove("FirstName");
84+
employeesSet.Tables["Employees"].Columns.Remove("Title");
85+
DataTestUtility.AssertEqualsWithDescription(6, employeesSet.Tables["Employees"].Columns.Count, "Unexpected columns count after column removal.");
86+
87+
DataSet dataSet = new();
88+
adapter.Fill(dataSet);
89+
DataTestUtility.AssertEqualsWithDescription(1, dataSet.Tables.Count, "Unexpected tables count after fill.");
90+
DataTestUtility.AssertEqualsWithDescription(9, dataSet.Tables[0].Columns.Count, "Unexpected column after fill.");
91+
92+
DataSet dataSet2 = new();
93+
adapter.Fill(dataSet2, 0, 2, "Employees");
94+
DataTestUtility.AssertEqualsWithDescription(1, dataSet2.Tables.Count, "Unexpected tables count after fill.");
95+
DataTestUtility.AssertEqualsWithDescription(2, dataSet2.Tables[0].Rows.Count, "Unexpected row count after fill.");
96+
DataTestUtility.AssertEqualsWithDescription(9, dataSet2.Tables[0].Columns.Count, "Unexpected column after fill.");
97+
98+
DataTable table = new();
99+
adapter.Fill(table);
100+
DataTestUtility.AssertEqualsWithDescription(9, table.Columns.Count, "Unexpected columns count.");
101+
102+
DataTable table2 = new();
103+
adapter.Fill(0, 2, table2);
104+
DataTestUtility.AssertEqualsWithDescription(9, table2.Columns.Count, "Unexpected columns count.");
105+
DataTestUtility.AssertEqualsWithDescription(2, table2.Rows.Count, "Unexpected rows count.");
106+
}
107+
108+
// TODO Synapse: Remove Northwind dependency by creating required tables in setup.
109+
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
110+
public void FillShouldAllowRetryLogicProviderToBeInvoked()
111+
{
112+
int maxRetries = 3;
113+
int expectedAttempts = maxRetries - 1;
114+
int retryCount = 0;
115+
116+
SqlRetryLogicOption options = new()
73117
{
74-
DataSet employeesSet = new DataSet();
75-
DataTestUtility.AssertEqualsWithDescription(0, employeesSet.Tables.Count, "Unexpected tables count before fill.");
76-
adapter.Fill(employeesSet, "Employees");
77-
78-
DataTestUtility.AssertEqualsWithDescription(1, employeesSet.Tables.Count, "Unexpected tables count after fill.");
79-
DataTestUtility.AssertEqualsWithDescription("Employees", employeesSet.Tables[0].TableName, "Unexpected table name.");
80-
81-
DataTestUtility.AssertEqualsWithDescription(9, employeesSet.Tables["Employees"].Columns.Count, "Unexpected columns count.");
82-
employeesSet.Tables["Employees"].Columns.Remove("LastName");
83-
employeesSet.Tables["Employees"].Columns.Remove("FirstName");
84-
employeesSet.Tables["Employees"].Columns.Remove("Title");
85-
DataTestUtility.AssertEqualsWithDescription(6, employeesSet.Tables["Employees"].Columns.Count, "Unexpected columns count after column removal.");
86-
}
118+
NumberOfTries = maxRetries,
119+
DeltaTime = TimeSpan.FromMilliseconds(100),
120+
MaxTimeInterval = TimeSpan.FromMilliseconds(500),
121+
TransientErrors = new int[] { 26, 4060, 233, -1, 17142, -2, 2812 }
122+
};
123+
SqlRetryLogicBaseProvider provider = SqlConfigurableRetryFactory.CreateFixedRetryProvider(options);
124+
125+
string query = "WAITFOR DELAY '00:00:02';SELECT 1";
126+
SqlConnectionStringBuilder builder = new(DataTestUtility.TCPConnectionString)
127+
{
128+
ConnectTimeout = 1
129+
};
130+
131+
using var connection = new SqlConnection(builder.ConnectionString);
132+
using SqlCommand command = new(query, connection);
133+
command.CommandTimeout = 1;
134+
command.RetryLogicProvider = provider;
135+
command.RetryLogicProvider.Retrying += (object sender, SqlRetryingEventArgs e) =>
136+
{
137+
retryCount = e.RetryCount;
138+
Assert.Equal(e.RetryCount, e.Exceptions.Count);
139+
Assert.NotEqual(TimeSpan.Zero, e.Delay);
140+
};
141+
142+
connection.Open();
143+
144+
AggregateException exception = Assert.Throws<AggregateException>(() =>
145+
{
146+
DataTable dt = new();
147+
using (SqlDataAdapter adapter = new(command))
148+
{
149+
adapter.Fill(dt);
150+
}
151+
});
152+
153+
Assert.Contains($"The number of retries has exceeded the maximum of {maxRetries} attempt(s)", exception.Message);
154+
Assert.Equal(expectedAttempts, retryCount);
87155
}
88156

89157
// TODO Synapse: Remove Northwind dependency by creating required tables in setup.

0 commit comments

Comments
 (0)