Laden...

Connection offen lassen oder gleich schließen?

Erstellt von Paulo vor 16 Jahren Letzter Beitrag vor 16 Jahren 3.744 Views
P
Paulo Themenstarter:in
172 Beiträge seit 2005
vor 16 Jahren
Connection offen lassen oder gleich schließen?

verwendetes Datenbanksystem: SQL Server 2005

Was ist besser:


            string ConnectionString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString;
            SqlConnection cn;
            cn = new SqlConnection(ConnectionString);

            SqlCommand cmd = new SqlCommand();
            cmd.Connection = cn;
            if (rrsID != 0)
            {
                cmd.CommandText = "SELECT rrs FROM sd_sec WHERE sID=@sID";
                cmd.Parameters.AddWithValue("sID", sID);
                cn.Open();
                rrs = cmd.ExecuteScalar().ToString();                
                cmd.Parameters.Clear();                  
                cmd.CommandText = "IF NOT EXISTS (SELECT bID FROM gf_bl WHERE brrs=@brrs) INSERT INTO gf_bl (brrs, UserID) VALUES (@brrs, @UserID)";
                cmd.Parameters.AddWithValue("brrs", rrs);
                cmd.Parameters.AddWithValue("UserID", UserID);                
                cmd.ExecuteNonQuery();                
                cmd.Parameters.Clear();                       
                cmd.CommandText = "DELETE FROM sd_sec WHERE rrsID=@rrsID";
                cmd.Parameters.AddWithValue("rrsID", rrsID);                
                cmd.ExecuteNonQuery();
                cn.Close();
            }
            cmd.Dispose();

Oder die Version die gleich die Connection nach jedem Execute wieder schließt?


            string ConnectionString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString;
            SqlConnection cn;
            cn = new SqlConnection(ConnectionString);

            SqlCommand cmd = new SqlCommand();
            cmd.Connection = cn;
            if (rrsID != 0)
            {
                cmd.CommandText = "SELECT rrs FROM sd_sec WHERE sID=@sID";
                cmd.Parameters.AddWithValue("sID", sID);

                cn.Open();
                rrs = cmd.ExecuteScalar().ToString();                
                cn.Close();

                cmd.Parameters.Clear();                  
                cmd.CommandText = "IF NOT EXISTS (SELECT bID FROM gf_bl WHERE brrs=@brrs) INSERT INTO gf_bl (brrs, UserID) VALUES (@brrs, @UserID)";
                cmd.Parameters.AddWithValue("brrs", rrs);
                cmd.Parameters.AddWithValue("UserID", UserID);                

                cn.Open();
                cmd.ExecuteNonQuery();                
                cn.Close();

                cmd.Parameters.Clear();                       
                cmd.CommandText = "DELETE FROM sd_sec WHERE rrsID=@rrsID";
                cmd.Parameters.AddWithValue("rrsID", rrsID);                

               cn.Open();
                cmd.ExecuteNonQuery();
                cn.Close();
            }
            cmd.Dispose();

J
3.331 Beiträge seit 2006
vor 16 Jahren

Schon oft diskutiert und erläutert: Eine **DbConnection **ist so spät zu öffnen wie nötig und so früh zu schließen wie möglich. Damit man das nicht vergisst und einfach regelt, passt am besten folgende Konstruktion:

using(DbConnection conn = new DbConnection() {
  //  jetzt alles andere vorbereiten
  conn.Open();
  //  Maßnahmen durchführen
  conn.Close();
  //  darauf kann auch noch verzichtet werden, weil die Connection
  //  sowieso gleich "weg" ist
}

Gruß Jürgen

E
124 Beiträge seit 2006
vor 16 Jahren

Hallo juetho

Mir war auch klar, dass man eine Connection schließen soll, wenn man sie nicht braucht. Ich persönlich mache es so, dass ich sie schließe, sobald die Leerlaufzeit in den Sekundenbereich geht. In seinem Beispiel erstellt Paulo zwischendurch nur ein neues Commando und braucht sie dann wieder. Er öffnet sie also 1 ms, nachdem er sie geschlossen hat, wieder. Das erscheint mir nicht richtig.

Deiner Ansicht nach wäre also auch folgender Code richtig, oder?

for (int i = 0; i < 10; i++)
{
  conn.Open();
  //  Maßnahmen durchführen
  conn.Close();
}

Oder?

Grüße
Elric

J
3.331 Beiträge seit 2006
vor 16 Jahren

Original von Elric
Mir war auch klar, dass man eine Connection schließen soll, wenn man sie nicht braucht. Ich persönlich mache es so, dass ich sie schließe, sobald die Leerlaufzeit in den Sekundenbereich geht. In seinem Beispiel erstellt Paulo zwischendurch nur ein neues Commando und braucht sie dann wieder. Er öffnet sie also 1 ms, nachdem er sie geschlossen hat, wieder. Das erscheint mir nicht richtig.

Ich weiß nicht, wie "Puristen" das sehen. Aus meiner Sicht wäre es ebenfalls nicht sinnvoll. Deshalb meine Formulierungen "so spät zu öffnen wie nötig und so früh zu schließen wie möglich" und "Maßnahmen durchführen" im Kommentar. Das schließt durchaus mehrere Befehle hintereinander ein.

Bei Deinem Code-Beispiel können conn.Open/Close also vor bzw. hinter die Schleife kommen.

Jürgen

P
Paulo Themenstarter:in
172 Beiträge seit 2005
vor 16 Jahren

Original von Elric
Mir war auch klar, dass man eine Connection schließen soll, wenn man sie nicht braucht. Ich persönlich mache es so, dass ich sie schließe, sobald die Leerlaufzeit in den Sekundenbereich geht.

Das hört sich für mich nach einer guten Faustregel an, danke an euch beide!

F
10.010 Beiträge seit 2004
vor 16 Jahren

Das ist aber auch nicht die richtige lösung, denn dann hast Du ja "globale"
ADO.NET Objekte.

Die Faustformel ist, Die Connection genau solange geöffnet zu halten, um
eine zusammengehörige Aktion auszuführen.
Dies ist schon wegen der natürlich zu benutzenden Transactions zu beachten.

E
124 Beiträge seit 2006
vor 16 Jahren

Hallo FZelle

Du hast natürlich recht, aber eigentlich verlagerst Du die Diskussion nur. Nach Deiner Aussage muss man nämlich erst überlegen, was ist eine "zusammengehörige Aktion"?

In dem Fall der For-Schleife wären also die 10 Durchgänge eine zusammengehörige Aktion. Was aber (und das konstruiere ich jetzt nicht, sondern genau den Fall habe ich), wenn eventuell Pausen dazwischen sind. Bsp:Ich möchte eineTabelle pollen:

while (Bedingung)
{
     //Hier ist die Abfrage

    Sleep(WarteZeit);
}

Würdest Du in diesem Fall auch das open/close innnerhalb der Schleife machen?
Oder ist es nicht abhängig davon welchen Wert die Wartezeit annehmen kann?
Sollte WarteZeit gegen 0 gehen, hat man eine zusammenhängende Aktion, ab welchem Wert hat man diese nicht mehr?

Grüße
Elric