diff --git a/doc/snippets/Microsoft.Data.SqlClient/SqlConfigurableRetryFactory.xml b/doc/snippets/Microsoft.Data.SqlClient/SqlConfigurableRetryFactory.xml index 730a592b6f..379a29a1f8 100644 --- a/doc/snippets/Microsoft.Data.SqlClient/SqlConfigurableRetryFactory.xml +++ b/doc/snippets/Microsoft.Data.SqlClient/SqlConfigurableRetryFactory.xml @@ -1,120 +1,9 @@ - + Provides different retry logic providers with a common list of transient errors. - - - The following table shows the inner transient error list. - - - - Error Number - Description - - - 1204 - - The instance of the SQL Server Database Engine cannot obtain a LOCK resource at this time. Rerun your statement when there are fewer active users. Ask the database administrator to check the lock and memory configuration for this instance, or to check for long-running transactions. - - - - 1205 - - Transaction (Process ID) was deadlocked on resources with another process and has been chosen as the deadlock victim. Rerun the transaction. - - - - 1222 - Lock request time out period exceeded. - - - 49918 - Cannot process request. Not enough resources to process request. - - - 49919 - - Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". - - - - 49920 - Cannot process request. Too many operations in progress for subscription "%ld". - - - 4060 - Cannot open database "%.*ls" requested by the login. The login failed. - - - 4221 - - Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'. The replica is not available for login because row versions are missing for transactions that were in-flight when the replica was recycled. The issue can be resolved by rolling back or committing the active transactions on the primary replica. Occurrences of this condition can be minimized by avoiding long write transactions on the primary. - - - - 40143 - The service has encountered an error processing your request. Please try again. - - - 40613 - - Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them the session tracing ID of '%.*ls'. - - - - 40501 - The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d. - - - 40540 - The service has encountered an error processing your request. Please try again. - - - 40197 - The service has encountered an error processing your request. Please try again. Error code %d. - - - 10929 - - Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. For more information, see https://learn.microsoft.com/azure/azure-sql/database/resource-limits-logical-server. Otherwise, please try again later. - - - - 10928 - - Resource ID: %d. The %s limit for the database is %d and has been reached. For more information, see https://learn.microsoft.com/azure/azure-sql/database/resource-limits-logical-server. - - - - 10060 - - An error has occurred while establishing a connection to the server. When connecting to SQL Server, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: TCP Provider, error: 0 - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.) (Microsoft SQL Server, Error: 10060) - - - - 10054 - The data value for one or more columns overflowed the type used by the provider. - - - 10053 - Could not convert the data value due to reasons other than sign mismatch or overflow. - - - 997 - - A connection was successfully established with the server, but then an error occurred during the login process. (provider: Named Pipes Provider, error: 0 - Overlapped I/O operation is in progress) - - - - 233 - - A connection was successfully established with the server, but then an error occurred during the login process. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.) (Microsoft SQL Server, Error: 233) - - - - @@ -128,8 +17,8 @@ -> [!NOTE] -> The inner enumerator includes randomization to prevent multiple instances of the client from performing subsequent retry attempts at the same time. + > [!NOTE] + > The inner enumerator includes randomization to prevent multiple instances of the client from performing subsequent retry attempts at the same time. @@ -138,21 +27,31 @@ If at least one of the following conditions occurs: - - is less than 1 or bigger than 60. - - - is bigger than 120 seconds. - - - is bigger than 120 seconds. - - - is bigger than 120 seconds. - - - is not less than . - + + + is less than 1 or bigger than 60. + + + + + is bigger than 120 seconds. + + + + + is bigger than 120 seconds. + + + + + is bigger than 120 seconds. + + + + + is not less than . + + @@ -168,8 +67,8 @@ -> [!NOTE] -> The inner enumerator includes randomization to prevent multiple instances of the client from performing subsequent retry attempts at the same time. + > [!NOTE] + > The inner enumerator includes randomization to prevent multiple instances of the client from performing subsequent retry attempts at the same time. @@ -178,21 +77,31 @@ If at least one of the following conditions occurs: - - is less than 1 or bigger than 60. - - - is bigger than 120 seconds. - - - is bigger than 120 seconds. - - - is bigger than 120 seconds. - - - is not less than . - + + + is less than 1 or bigger than 60. + + + + + is bigger than 120 seconds. + + + + + is bigger than 120 seconds. + + + + + is bigger than 120 seconds. + + + + + is not less than . + + @@ -208,8 +117,8 @@ -> [!NOTE] -> The inner enumerator includes randomization to prevent multiple instances of the client from performing subsequent retry attempts at the same time. + > [!NOTE] + > The inner enumerator includes randomization to prevent multiple instances of the client from performing subsequent retry attempts at the same time. @@ -218,21 +127,31 @@ If at least one of the following conditions occurs: - - is less than 1 or bigger than 60. - - - is bigger than 120 seconds. - - - is bigger than 120 seconds. - - - is bigger than 120 seconds. - - - is not less than . - + + + is less than 1 or bigger than 60. + + + + + is bigger than 120 seconds. + + + + + is bigger than 120 seconds. + + + + + is bigger than 120 seconds. + + + + + is not less than . + + @@ -245,10 +164,126 @@ -> [!NOTE] -> The returned provider of this function performs a single execution without any retry logic. + > [!NOTE] + > The returned provider of this function performs a single execution without any retry logic. + + + This list may change at any time as the underlying implementation changes, and will not be considered a breaking API change. Applications should not depend on this list containing any particular error codes. + + + + The following table shows the inner transient error list. + + + + Error Number + Description + + + 233 + + A connection was successfully established with the server, but then an error occurred during the login process. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.) (Microsoft SQL Server, Error: 233) + + + + 997 + + A connection was successfully established with the server, but then an error occurred during the login process. (provider: Named Pipes Provider, error: 0 - Overlapped I/O operation is in progress) + + + + 1204 + + The instance of the SQL Server Database Engine cannot obtain a LOCK resource at this time. Rerun your statement when there are fewer active users. Ask the database administrator to check the lock and memory configuration for this instance, or to check for long-running transactions. + + + + 1205 + + Transaction (Process ID) was deadlocked on resources with another process and has been chosen as the deadlock victim. Rerun the transaction. + + + + 1222 + Lock request time out period exceeded. + + + 4060 + Cannot open database "%.*ls" requested by the login. The login failed. + + + 4221 + + Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'. The replica is not available for login because row versions are missing for transactions that were in-flight when the replica was recycled. The issue can be resolved by rolling back or committing the active transactions on the primary replica. Occurrences of this condition can be minimized by avoiding long write transactions on the primary. + + + + 10060 + + An error has occurred while establishing a connection to the server. When connecting to SQL Server, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: TCP Provider, error: 0 - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.) (Microsoft SQL Server, Error: 10060) + + + + 10928 + + Resource ID: %d. The %s limit for the database is %d and has been reached. For more information, see https://learn.microsoft.com/azure/azure-sql/database/resource-limits-logical-server. + + + + 10929 + + Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. For more information, see https://learn.microsoft.com/azure/azure-sql/database/resource-limits-logical-server. Otherwise, please try again later. + + + + 40143 + The service has encountered an error processing your request. Please try again. + + + 40197 + The service has encountered an error processing your request. Please try again. Error code %d. + + + 40501 + The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d. + + + 40540 + The service has encountered an error processing your request. Please try again. + + + 40613 + + Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them the session tracing ID of '%.*ls'. + + + + 42108 + Cannot connect to the SQL pool since it is paused. Please resume the SQL pool and try again. + + + 42109 + The SQL pool is warming up. Please try again. + + + 49918 + Cannot process request. Not enough resources to process request. + + + 49919 + + Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". + + + + 49920 + Cannot process request. Too many operations in progress for subscription "%ld". + + + + diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs index 58da74a33d..a2189fe588 100644 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs @@ -1867,6 +1867,8 @@ public sealed class SqlRetryLogicOption /// public sealed class SqlConfigurableRetryFactory { + /// + public static System.Collections.ObjectModel.ReadOnlyCollection BaselineTransientErrors { get { throw null; } } /// public static SqlRetryLogicBaseProvider CreateExponentialRetryProvider(SqlRetryLogicOption retryLogicOption) { throw null; } /// diff --git a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs index 049d91fe86..b8f863aa66 100644 --- a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.cs @@ -1848,6 +1848,8 @@ public sealed class SqlRetryLogicOption /// public sealed class SqlConfigurableRetryFactory { + /// + public static System.Collections.ObjectModel.ReadOnlyCollection BaselineTransientErrors { get { throw null; } } /// public static SqlRetryLogicBaseProvider CreateExponentialRetryProvider(SqlRetryLogicOption retryLogicOption) { throw null; } /// diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryFactory.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryFactory.cs index 859c3ef510..c04561da46 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryFactory.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Reliability/SqlConfigurableRetryFactory.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Diagnostics; namespace Microsoft.Data.SqlClient @@ -36,31 +37,35 @@ public sealed class SqlRetryLogicOption public sealed class SqlConfigurableRetryFactory { private readonly static object s_syncObject = new(); + /// Default known transient error numbers. + // We use a HashSet internally for O(1) lookup performance in the hot path. The public API exposes a ReadOnlyCollection. private static readonly HashSet s_defaultTransientErrors - = new HashSet - { + = [ + 233, // A connection was successfully established with the server, but then an error occurred during the login process. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.) (Microsoft SQL Server, Error: 233) + 997, // A connection was successfully established with the server, but then an error occurred during the login process. (provider: Named Pipes Provider, error: 0 - Overlapped I/O operation is in progress) 1204, // The instance of the SQL Server Database Engine cannot obtain a LOCK resource at this time. Rerun your statement when there are fewer active users. Ask the database administrator to check the lock and memory configuration for this instance, or to check for long-running transactions. 1205, // Transaction (Process ID) was deadlocked on resources with another process and has been chosen as the deadlock victim. Rerun the transaction 1222, // Lock request time out period exceeded. - 49918, // Cannot process request. Not enough resources to process request. - 49919, // Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". - 49920, // Cannot process request. Too many operations in progress for subscription "%ld". 4060, // Cannot open database "%.*ls" requested by the login. The login failed. 4221, // Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'. The replica is not available for login because row versions are missing for transactions that were in-flight when the replica was recycled. The issue can be resolved by rolling back or committing the active transactions on the primary replica. Occurrences of this condition can be minimized by avoiding long write transactions on the primary. + 10060, // An error has occurred while establishing a connection to the server. When connecting to SQL Server, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: TCP Provider, error: 0 - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.) (Microsoft SQL Server, Error: 10060) + 10928, // Resource ID: %d. The %s limit for the database is %d and has been reached. For more information, see http://go.microsoft.com/fwlink/?LinkId=267637. + 10929, // Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. For more information, see http://go.microsoft.com/fwlink/?LinkId=267637. Otherwise, please try again later. 40143, // The service has encountered an error processing your request. Please try again. - 40613, // Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them the session tracing ID of '%.*ls'. + 40197, // The service has encountered an error processing your request. Please try again. Error code %d. 40501, // The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d. 40540, // The service has encountered an error processing your request. Please try again. - 40197, // The service has encountered an error processing your request. Please try again. Error code %d. + 40613, // Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them the session tracing ID of '%.*ls'. 42108, // Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again. 42109, // The SQL pool is warming up. Please try again. - 10929, // Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. For more information, see http://go.microsoft.com/fwlink/?LinkId=267637. Otherwise, please try again later. - 10928, // Resource ID: %d. The %s limit for the database is %d and has been reached. For more information, see http://go.microsoft.com/fwlink/?LinkId=267637. - 10060, // An error has occurred while establishing a connection to the server. When connecting to SQL Server, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: TCP Provider, error: 0 - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.) (Microsoft SQL Server, Error: 10060) - 997, // A connection was successfully established with the server, but then an error occurred during the login process. (provider: Named Pipes Provider, error: 0 - Overlapped I/O operation is in progress) - 233 // A connection was successfully established with the server, but then an error occurred during the login process. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.) (Microsoft SQL Server, Error: 233) - }; + 49918, // Cannot process request. Not enough resources to process request. + 49919, // Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". + 49920 // Cannot process request. Too many operations in progress for subscription "%ld". + ]; + + /// + public static ReadOnlyCollection BaselineTransientErrors { get; } = new([.. s_defaultTransientErrors]); /// public static SqlRetryLogicBaseProvider CreateExponentialRetryProvider(SqlRetryLogicOption retryLogicOption) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicTestHelper.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicTestHelper.cs index c9a64e5ef1..5c2aef92eb 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicTestHelper.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/RetryLogic/RetryLogicTestHelper.cs @@ -4,8 +4,6 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Text.RegularExpressions; using Xunit; @@ -13,36 +11,16 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests { public class RetryLogicTestHelper { - private static readonly HashSet s_defaultTransientErrors - = new HashSet - { - 1204, // The instance of the SQL Server Database Engine cannot obtain a LOCK resource at this time. Rerun your statement when there are fewer active users. Ask the database administrator to check the lock and memory configuration for this instance, or to check for long-running transactions. - 1205, // Transaction (Process ID) was deadlocked on resources with another process and has been chosen as the deadlock victim. Rerun the transaction - 1222, // Lock request time out period exceeded. - 49918, // Cannot process request. Not enough resources to process request. - 49919, // Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". - 49920, // Cannot process request. Too many operations in progress for subscription "%ld". - 4060, // Cannot open database "%.*ls" requested by the login. The login failed. - 4221, // Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'. The replica is not available for login because row versions are missing for transactions that were in-flight when the replica was recycled. The issue can be resolved by rolling back or committing the active transactions on the primary replica. Occurrences of this condition can be minimized by avoiding long write transactions on the primary. - 42108, // Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again. - 42109, // The SQL pool is warming up. Please try again. - 40143, // The service has encountered an error processing your request. Please try again. - 40613, // Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them the session tracing ID of '%.*ls'. - 40501, // The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d. - 40540, // The service has encountered an error processing your request. Please try again. - 40197, // The service has encountered an error processing your request. Please try again. Error code %d. - 10929, // Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. For more information, see http://go.microsoft.com/fwlink/?LinkId=267637. Otherwise, please try again later. - 10928, // Resource ID: %d. The %s limit for the database is %d and has been reached. For more information, see http://go.microsoft.com/fwlink/?LinkId=267637. - 10060, // An error has occurred while establishing a connection to the server. When connecting to SQL Server, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: TCP Provider, error: 0 - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.) (Microsoft SQL Server, Error: 10060) - 997, // A connection was successfully established with the server, but then an error occurred during the login process. (provider: Named Pipes Provider, error: 0 - Overlapped I/O operation is in progress) - 233, // A connection was successfully established with the server, but then an error occurred during the login process. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.) (Microsoft SQL Server, Error: 233) - 64, - 20, - 0, - -2, // Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding. - 207, // invalid column name - 18456 // Using managed identity in Azure Sql Server throws 18456 for non-existent database instead of 4060. - }; + private static readonly HashSet s_defaultTransientErrors = + [ + .. SqlConfigurableRetryFactory.BaselineTransientErrors, + -2, // Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding. + 0, // A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: TCP Provider, error: 0 - A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.) + 20, // The instance of SQL Server you attempted to connect to does not support encryption. + 64, // A connection was successfully established with the server, but then an error occurred during the login process. (provider: TCP Provider, error: 0 - The specified network name is no longer available.) + 207, // Invalid column name + 18456 // Using managed identity in Azure Sql Server throws 18456 for non-existent database instead of 4060. + ]; public static readonly Regex FilterDmlStatements = new Regex( @"\b(INSERT( +INTO)|UPDATE|DELETE|TRUNCATE)\b",