Skip to content

Negative Transient Errors Discarded by SqlConfigurableRetryLogicLoader since V5.2.0 #2890

@griffitd

Description

@griffitd

Describe the bug

Our most common error number from a sleeping Azure database is -2. It is no longer possible to retry on this error number because it is negative (V5.2.0 not working; V5.1.6 working).

The bug was introduced here: 23ca8e7 (SqlConfigurableRetryLogicLoader.cs).

Convert.ToInt32(x) was replaced with int.TryParse(parts[index], System.Globalization.NumberStyles.AllowLeadingWhite | System.Globalization.NumberStyles.AllowTrailingWhite, null, out int value)

Because NumberStyles are used, negative numbers are not parsed unless AllowLeadingSign is included.

I would think, the simple fix is to add System.Globalization.NumberStyles.AllowLeadingSign here.

To reproduce

Add the config sections to your app.config file. Run any SQL, as per the example. (Note -2 is the last error listed.)

  <configSections>
    <section name="SqlConfigurableRetryLogicConnection" type="Microsoft.Data.SqlClient.SqlConfigurableRetryConnectionSection, Microsoft.Data.SqlClient"/>
  </configSections>

  <SqlConfigurableRetryLogicConnection retryMethod ="CreateIncrementalRetryProvider" numberOfTries="5" deltaTime="00:00:10" maxTime="00:00:40"
	transientErrors="1204, 1205, 1222, 49918, 49919, 49920, 4060, 4221, 40143, 40613, 40501, 40540, 40197, 42108, 42109, 10929, 10928, 10060, 997, 233, -2" />


        public void SelectOne()
        {
            using (var connection = new SqlConnection(_connectionString))
            using (var command = new SqlCommand("SELECT 1", connection))
            {
                try
                {
                connection.Open();
                command.ExecuteNonQuery();
                }
                catch (SqlException ex)
                {
                    LogException(ex, "Error selecting 1");
                    throw;
                }
            }
        }

Expected behavior

When an Azure database is asleep and -2 is returned as the error number, the code should retry.

Retrying can be spotted in the trace. This is logged correctly with V5.1.6, but does not get logged with V5.2.0.

<sc.SqlConfigurableRetryFactory.TransientErrorsCondition|ERR|CATCH> Found a transient error: number = <-2>, message = <Connection Timeout Expired. The timeout period elapsed during the post-login phase. The connection could have timed out while waiting for server to complete the login process and respond; Or it could have timed out while attempting to create multiple active connections. The duration spent while attempting to connect to this server was - [Pre-Login] initialization=253; handshake=134; [Login] initialization=3; authentication=22; [Post-Login] complete=14015; >

Further technical details

Microsoft.Data.SqlClient version: (V5.2.0 not working; V5.1.6 working correctly)
.NET target: (net8.0)
SQL Server version: (Azure database)
Operating system: (Windows 10 and Linux)

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    Good First Issue ✨Issues that are simple enough for newcomersHotfix Candidate 🚑Issues/PRs that are candidate for backporting to earlier supported versions.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions