Eventi
31 mar, 23 - 2 apr, 23
Il più grande evento di apprendimento di SQL, Infrastruttura e Power BI. 31 marzo - 2 aprile. Usare il codice FABINSIDER per salvare $400.
Registrati oggiQuesto browser non è più supportato.
Esegui l'aggiornamento a Microsoft Edge per sfruttare le funzionalità più recenti, gli aggiornamenti della sicurezza e il supporto tecnico.
In questo argomento viene fornito un esempio di codice C# che illustra una logica di ripetizione dei tentativi personalizzata. La logica di ripetizione dei tentativi garantisce affidabilità. È progettata per elaborare correttamente gli errori o guasti temporanei che tendono a risolversi se il programma attende qualche secondo ed effettua un nuovo tentativo.
L'origine di un errore temporaneo può essere:
Le classi ADO.NET per la connessione all'istanza locale di Microsoft SQL Server possono anche connettersi al database SQL di Azure. Tuttavia, le classi ADO.NET non forniscono autonomamente tutta la solidità e l’affidabilità necessarie per l’uso in un ambiente di produzione. Il programma client può incorrere in guasti temporanei da cui deve poter eseguire un ripristino automatico e continuare a funzionare.
Il programma deve distinguere gli errori temporanei dagli errori persistenti. Gli errori temporanei sono condizioni di errore che possono scomparire entro un breve periodo di tempo, ad esempio problemi momentanei della rete. Un esempio di errore persistente può essere l'uso da parte del programma di un nome scritto in modo errato per il database di destinazione: in questo caso l'errore "Database non trovato" è persistente e non è possibile cancellarlo entro un breve periodo di tempo.
L'elenco dei numeri di errore classificati come errori temporanei è disponibile nell'elenco dei messaggi di errore per le applicazioni client del database SQL
In questo esempio si presuppone che sia installato .NET Framework 4.6.2 o versione successiva. L'esempio di codice C# è costituito da un file denominato Program.cs. Il relativo codice viene specificato nella sezione successiva.
È possibile compilare l'esempio con i passaggi seguenti:
Incollare questo codice nel file Program.cs .
È necessario modificare le stringhe per nome del server, password e così via. È possibile trovare queste stringhe nel metodo denominato GetSqlConnectionString.
NOTA: la stringa di connessione per il nome del server è pensata per il database SQL di Azure, perché include il prefisso di quattro caratteri di tcp:. ma è possibile modificare la stringa del server per connettersi a Microsoft SQL Server.
using System;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using System.Threading;
namespace RetryAdo2;
public class Program
{
public static int Main(string[] args)
{
bool succeeded = false;
const int totalNumberOfTimesToTry = 4;
int retryIntervalSeconds = 10;
for (int tries = 1; tries <= totalNumberOfTimesToTry; tries++)
{
try
{
if (tries > 1)
{
Console.WriteLine(
"Transient error encountered. Will begin attempt number {0} of {1} max...",
tries,
totalNumberOfTimesToTry
);
Thread.Sleep(1000 * retryIntervalSeconds);
retryIntervalSeconds = Convert.ToInt32(retryIntervalSeconds * 1.5);
}
AccessDatabase();
succeeded = true;
break;
}
catch (SqlException sqlExc) {
if (TransientErrorNumbers.Contains(sqlExc.Number))
{
Console.WriteLine("{0}: transient occurred.", sqlExc.Number);
continue;
}
Console.WriteLine(sqlExc);
succeeded = false;
break;
}
catch (TestSqlException sqlExc) {
if (TransientErrorNumbers.Contains(sqlExc.Number))
{
Console.WriteLine("{0}: transient occurred. (TESTING.)", sqlExc.Number);
continue;
}
Console.WriteLine(sqlExc);
succeeded = false;
break;
}
catch (Exception e)
{
Console.WriteLine(e);
succeeded = false;
break;
}
}
if (!succeeded) {
Console.WriteLine("ERROR: Unable to access the database!");
return 1;
}
return 0;
}
/// <summary>
/// Connects to the database, reads,
/// prints results to the console.
/// </summary>
static void AccessDatabase() {
//throw new TestSqlException(4060); //(7654321); // Uncomment for testing.
using var sqlConnection = new SqlConnection(GetSqlConnectionString());
using var dbCommand = sqlConnection.CreateCommand();
dbCommand.CommandText =
@"
SELECT TOP 3
ob.name,
CAST(ob.object_id as nvarchar(32)) as [object_id]
FROM sys.objects as ob
WHERE ob.type='IT'
ORDER BY ob.name;";
sqlConnection.Open();
var dataReader = dbCommand.ExecuteReader();
while (dataReader.Read())
{
Console.WriteLine(
"{0}\t{1}",
dataReader.GetString(0),
dataReader.GetString(1)
);
}
}
/// <summary>
/// You must edit the four 'my' string values.
/// </summary>
/// <returns>An ADO.NET connection string.</returns>
static private string GetSqlConnectionString()
{
// Prepare the connection string to Azure SQL Database.
var sqlConnectionSB = new SqlConnectionStringBuilder
{
// Change these values to your values.
DataSource = "tcp:myazuresqldbserver.database.windows.net,1433", //["Server"]
InitialCatalog = "MyDatabase", //["Database"]
UserID = "MyLogin", // "@yourservername" as suffix sometimes.
Password = "MyPassword",
// Adjust these values if you like. (ADO.NET 4.5.1 or later.)
ConnectRetryCount = 3,
ConnectRetryInterval = 10, // Seconds.
// Leave these values as they are.
IntegratedSecurity = false,
Encrypt = true,
ConnectTimeout = 30
};
return sqlConnectionSB.ToString();
}
static List<int> TransientErrorNumbers = new()
{
4060, 40197, 40501, 40613, 49918, 49919, 49920, 11001
};
}
/// <summary>
/// For testing retry logic, you can have method
/// AccessDatabase start by throwing a new
/// TestSqlException with a Number that does
/// or does not match a transient error number
/// present in TransientErrorNumbers.
/// </summary>
internal class TestSqlException : ApplicationException
{
internal TestSqlException(int testErrorNumber)
{
Number = testErrorNumber;
}
internal int Number { get; set; }
}
L’eseguibile RetryAdo2.exe non invia parametri. Per eseguire il file EXE:
database_firewall_rules_table 245575913
filestream_tombstone_2073058421 2073058421
filetable_updates_2105058535 2105058535
Per testare la logica di ripetizione dei tentativi è possibile simulare un errore temporaneo in diversi modi.
L'esempio di codice include:
//throw new TestSqlException(4060);
, da cui è possibile rimuovere il commento.Se si rimuove il commento dall'istruzione throw e si ricompila, l'esecuzione successiva di RetryAdo2.exe restituisce un output simile al seguente.
[C:\VS15\RetryAdo2\RetryAdo2\bin\Debug\]
>> RetryAdo2.exe
4060: transient occurred. (TESTING.)
Transient error encountered. Will begin attempt number 2 of 4 max...
4060: transient occurred. (TESTING.)
Transient error encountered. Will begin attempt number 3 of 4 max...
4060: transient occurred. (TESTING.)
Transient error encountered. Will begin attempt number 4 of 4 max...
4060: transient occurred. (TESTING.)
ERROR: Unable to access the database!
[C:\VS15\RetryAdo2\RetryAdo2\bin\Debug\]
>>
Per verificare se il codice gestisce correttamente gli errori persistenti, rieseguire il test precedente facendo attenzione a non usare il numero di un errore temporaneo effettivo, come 4060. Usare invece il numero fittizio 7654321. Il programma deve trattarlo come un errore persistente e ignorare qualsiasi ripetizione dei tentativi.
new QC.SqlConnectionStringBuilder()
.Per esplorare altre procedure consigliate e linee guida di progettazione, consultare Connessione al database SQL: collegamenti, migliori pratiche e linee guida di progettazione
Eventi
31 mar, 23 - 2 apr, 23
Il più grande evento di apprendimento di SQL, Infrastruttura e Power BI. 31 marzo - 2 aprile. Usare il codice FABINSIDER per salvare $400.
Registrati oggiTraining
Modulo
Implementare la gestione degli errori con Transact-SQL - Training
Implementare la gestione degli errori con Transact-SQL
Certificazione
Microsoft Certified: Azure Database Administrator Associate - Certifications
Amministrare un'infrastruttura di database SQL Server per database relazionali, ibridi, locali e cloud con le offerte di database relazionali Microsoft PaaS.
Documentazione
Contiene esempi di codice C# per la connessione a SQL Server, l'esecuzione di una query e l'inserimento di una riga.
Passaggio 2: Creare un database SQL per lo sviluppo ADO.NET - ADO.NET Provider for SQL Server
Informazioni su come creare un database SQL per lo sviluppo ADO.NET usando Microsoft.Data.SqlClient.
Introduzione al driver SqlClient - ADO.NET Provider for SQL Server
Introduzione all'uso del driver SqlClient. Informazioni sui passaggi di base per la configurazione dell'ambiente e la scrittura di un semplice esempio di codice.