In meiner Server-Anwendung möchte ich DB (SQL Server) verwenden, aber ich bin ziemlich unsicher, die beste Methode. Es gibt Clients, deren Anfragen in den Threadpool kommen und deren Verarbeitung daher asynchron ist. Jede Anfrage muss normalerweise in die DB lesen oder schreiben, also dachte ich an eine statische Methode, die eine Verbindung erstellt, die Abfrage ausführt und das Ergebnis zurückgibt. Ich bin nur besorgt, ob das Öffnen und Schließen der Verbindung ist nicht zu langsam und ob einige Verbindung Grenze nicht erreicht werden könnte? Ist dies ein guter Ansatz?
Antworten
Zu viele Anzeigen?IMHO ist es am besten, sich auf den ADO.NET-Verbindungspooling-Mechanismus zu verlassen und nicht zu versuchen, Datenbankverbindungen manuell zu verwalten. Schreiben Sie Ihre Datenzugriffsmethoden wie diese:
public void SomeMethod()
{
using (var connection = new SqlConnection(connectionString))
using (var command = connection.CreateCommand())
{
connection.Open();
command.CommandText = "SELECT Field1 FROM Table1";
using (var reader = command.ExecuteReader())
{
while(reader.Read())
{
// do something with the results
}
}
}
}
Dann können Sie diese Methode von jedem beliebigen Ort aus aufrufen, sie statisch machen, sie von Threads aus aufrufen, was auch immer. Denken Sie daran, dass der Aufruf von Dispose
auf der Verbindung wird diese nicht wirklich geschlossen. Sie wird an den Verbindungspool zurückgegeben, damit sie wieder verwendet werden kann.
Ich hatte genau das gleiche Problem wie Sie. Hatte riesige app, die ich begann, machen multithreaded. Vorteil über eine Verbindung offen und wiederverwendet wird, ist, dass Sie DB mehrere Male für Daten fragen können, wie neue Verbindung auf Anfrage erzeugt wird (keine Notwendigkeit, für andere Threads warten, um Daten zu beenden), und wenn zum Beispiel Sie verlieren Verbindung zu Sql (und es kann passieren, wenn das Netzwerk für eine Sekunde oder zwei geht) Sie haben immer zu überprüfen, ob Verbindung offen ist, bevor Sie Abfrage sowieso.
Dies ist mein Code für das Abrufen von Datenbankzeilen in MS SQL, aber andere Dinge sollten genau die gleiche Weise getan werden. Beachten Sie, dass sqlConnectOneTime(string varSqlConnectionDetails) den Fehler hat, null zurückzugeben, wenn es keine Verbindung gibt, so dass es einige Änderungen für Ihre Bedürfnisse braucht, oder die Abfrage wird fehlschlagen, wenn sql die Verbindung nicht herstellen kann. Sie müssen nur den richtigen Code hinzufügen, der dort behandelt wird :-) Ich hoffe, es wird Ihnen nützlich sein :-)
public const string sqlDataConnectionDetails = "Data Source=SQLSERVER\\SQLEXPRESS;Initial Cata....";
public static string sqlGetDatabaseRows(string varDefinedConnection) {
string varRows = "";
const string preparedCommand = @"
SELECT SUM(row_count) AS 'Rows'
FROM sys.dm_db_partition_stats
WHERE index_id IN (0,1)
AND OBJECTPROPERTY([object_id], 'IsMsShipped') = 0;";
using (var varConnection = Locale.sqlConnectOneTime(varDefinedConnection))
using (var sqlQuery = new SqlCommand(preparedCommand, varConnection))
using (var sqlQueryResult = sqlQuery.ExecuteReader())
while (sqlQueryResult.Read()) {
varRows = sqlQueryResult["Rows"].ToString();
}
return varRows;
}
public static SqlConnection sqlConnectOneTime(string varSqlConnectionDetails) {
SqlConnection sqlConnection = new SqlConnection(varSqlConnectionDetails);
try {
sqlConnection.Open();
} catch (Exception e) {
MessageBox.Show("Bd poczenia z serwerem SQL." + Environment.NewLine + Environment.NewLine + "Bd: " + Environment.NewLine + e, "Bd poczenia");
}
if (sqlConnection.State == ConnectionState.Open) {
return sqlConnection;
}
return null;
}
Zusammenfassung:
Definieren Sie eine globale Variable mit ConnectionDetails Ihres SQL Servers
Eine globale Methode zum Herstellen der Verbindung (Sie müssen die Null darin behandeln)
Verwendung von using
Verbindung, Sql-Abfrage und alles zu entsorgen, wenn die Methode des Lesens/Schreibens/Aktualisierens abgeschlossen ist.
Eine Sache, die Sie uns nicht mitgeteilt haben, die aber für eine angemessene Antwort nützlich wäre, ist welchen Grad der Belastung die Sie für Ihre Serveranwendung erwarten.
Für so ziemlich jede Antwort auf die obige Frage gilt jedoch, dass Sie sich keine Sorgen machen sollten. ADO.net/Sql Server bietet Verbindungspooling, das einen Teil des Overheads der Erstellung von Verbindungen bei jedem "var c = new SqlConnection(connectionString)"-Aufruf beseitigt.
Es überrascht, dass niemand das Pooling von Verbindungen erwähnt hat. Wenn Sie glauben, dass Sie eine große Anzahl von Anfragen haben werden, warum nicht einfach einen Pool mit einer minimalen Poolgröße von sagen wir 25 (beliebige Zahl hier, nicht schießen) und einer maximalen Poolgröße von sagen wir 200 einrichten. Dies verringert die Anzahl der Verbindungsversuche und stellt sicher, dass immer eine Verbindung auf Sie wartet, wenn Sie keine Verbindungshandles verlieren (was Sie unbedingt vermeiden sollten). Referenzartikel über das Pooling von Verbindungen: http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx Eine weitere Randbemerkung: Warum muss die Verbindungszeichenfolge im Code stehen? Legen Sie sie in der web.config oder app.config fest, um die Wartbarkeit zu gewährleisten. Ich musste Code "reparieren", der solche Dinge tat, und ich fluchte immer ausgiebig über den Programmierer, der für solche Dinge verantwortlich war.