// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Data.SqlClient; namespace Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal; /// /// Detects the exceptions caused by SQL Server transient failures. /// public static class SqlServerTransientExceptionDetector { /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// public static bool ShouldRetryOn(Exception? ex) { if (ex is SqlException sqlException) { foreach (SqlError err in sqlException.Errors) { switch (err.Number) { // SQL Error Code: 49920 // Cannot process request. Too many operations in progress for subscription "%ld". // The service is busy processing multiple requests for this subscription. // Requests are currently blocked for resource optimization. Query sys.dm_operation_status for operation status. // Wait until pending requests are complete or delete one of your pending requests and retry your request later. case 49920: // SQL Error Code: 49919 // Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". // The service is busy processing multiple create or update requests for your subscription or server. // Requests are currently blocked for resource optimization. Query sys.dm_operation_status for pending operations. // Wait till pending create or update requests are complete or delete one of your pending requests and // retry your request later. case 49919: // SQL Error Code: 49918 // Cannot process request. Not enough resources to process request. // The service is currently busy.Please retry the request later. case 49918: // SQL Error Code: 41839 // Transaction exceeded the maximum number of commit dependencies. case 41839: // SQL Error Code: 41325 // The current transaction failed to commit due to a serializable validation failure. case 41325: // SQL Error Code: 41305 // The current transaction failed to commit due to a repeatable read validation failure. case 41305: // SQL Error Code: 41302 // The current transaction attempted to update a record that has been updated since the transaction started. case 41302: // SQL Error Code: 41301 // Dependency failure: a dependency was taken on another transaction that later failed to commit. case 41301: // SQL Error Code: 40613 // Database XXXX on server YYYY is not currently available. Please retry the connection later. // If the problem persists, contact customer support, and provide them the session tracing ID of ZZZZZ. case 40613: // SQL Error Code: 40501 // The service is currently busy. Retry the request after 10 seconds. Code: (reason code to be decoded). case 40501: // SQL Error Code: 40197 // The service has encountered an error processing your request. Please try again. case 40197: // SQL Error Code: 20041 // Transaction rolled back. Could not execute trigger. Retry your transaction. case 20041: // SQL Error Code: 17197 // Login failed due to timeout; the connection has been closed. This error may indicate heavy server load. // Reduce the load on the server and retry login. case 17197: // SQL Error Code: 14355 // The MSSQLServerADHelper service is busy. Retry this operation later. case 14355: // SQL Error Code: 10936 // Resource ID : %d. The request limit for the elastic pool is %d and has been reached. // See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance. case 10936: // SQL Error Code: 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. case 10929: // SQL Error Code: 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. case 10928: // SQL Error Code: 10922 // %ls failed. Rerun the statement. case 10922: // SQL Error Code: 10060 // 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.)"} case 10060: // SQL Error Code: 10054 // A transport-level error has occurred when sending the request to the server. // (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.) case 10054: // SQL Error Code: 10053 // A transport-level error has occurred when receiving results from the server. // An established connection was aborted by the software in your host machine. case 10053: // SQL Error Code: 9515 // An XML schema has been altered or dropped, and the query plan is no longer valid. Please rerun the query batch. case 9515: // SQL Error Code: 8651 // Could not perform the operation because the requested memory grant was not available in resource pool '%ls' (%ld). // Rerun the query, reduce the query load, or check resource governor configuration setting. case 8651: // SQL Error Code: 8645 // A timeout occurred while waiting for memory resources to execute the query in resource pool '%ls' (%ld). Rerun the query. case 8645: // SQL Error Code: 8628 // A time out occurred while waiting to optimize the query. Rerun the query. case 8628: // SQL Error Code: 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. case 4221: // SQL Error Code: 4060 // Cannot open database "%.*ls" requested by the login. The login failed. case 4060: // SQL Error Code: 3966 // Transaction is rolled back when accessing version store. It was earlier marked as victim when the version store // was shrunk due to insufficient space in tempdb. This transaction was marked as a victim earlier because it may need // the row version(s) that have already been removed to make space in tempdb. Retry the transaction case 3966: // SQL Error Code: 3960 // Snapshot isolation transaction aborted due to update conflict. You cannot use snapshot isolation to access table '%.*ls' // directly or indirectly in database '%.*ls' to update, delete, or insert the row that has been modified or deleted // by another transaction. Retry the transaction or change the isolation level for the update/delete statement. case 3960: // SQL Error Code: 3935 // A FILESTREAM transaction context could not be initialized. This might be caused by a resource shortage. Retry the operation. case 3935: // SQL Error Code: 1807 // Could not obtain exclusive lock on database 'model'. Retry the operation later. case 1807: // SQL Error Code: 1221 // The Database Engine is attempting to release a group of locks that are not currently held by the transaction. // Retry the transaction. If the problem persists, contact your support provider. case 1221: // SQL Error Code: 1205 // Deadlock case 1205: // SQL Error Code: 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. case 1204: // SQL Error Code: 1203 // Process ID %d attempted to unlock a resource it does not own: %.*ls. Retry the transaction, because this error // may be caused by a timing condition. If the problem persists, contact the database administrator. case 1203: // SQL Error Code: 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) case 997: // SQL Error Code: 921 // Database '%.*ls' has not been recovered yet. Wait and try again. case 921: // SQL Error Code: 669 // The row object is inconsistent. Please rerun the query. case 669: // SQL Error Code: 617 // Descriptor for object ID %ld in database ID %d not found in the hash table during attempt to un-hash it. // A work table is missing an entry. Rerun the query. If a cursor is involved, close and reopen the cursor. case 617: // SQL Error Code: 601 // Could not continue scan with NOLOCK due to data movement. case 601: // SQL Error Code: 233 // The client was unable to establish a connection because of an error during connection initialization process before login. // Possible causes include the following: the client tried to connect to an unsupported version of SQL Server; // the server was too busy to accept new connections; or there was a resource limitation (insufficient memory or maximum // allowed connections) on the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by // the remote host.) case 233: // SQL Error Code: 121 // The semaphore timeout period has expired case 121: // SQL Error Code: 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.) case 64: // DBNETLIB Error Code: 20 // The instance of SQL Server you attempted to connect to does not support encryption. case 20: return true; // This exception can be thrown even if the operation completed successfully, so it's safer to let the application fail. // DBNETLIB Error Code: -2 // Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated. //case -2: } } return false; } return ex is TimeoutException; } }