[ havramm @ 10.07.2004. 15:08 ] @
Primetio sam zanimljivo ponasanje klasa SqlConnection i SqlCommand. Naime primetio sam da se uvek otvaraju dve konekcije prema SQL Server-u iako sam ocekivao da ce se otvoriti samo jedna. npr:

Code:

1:  SqlCommand cmd = new SqlCommand(spName, connection);
2:  cmd.CommandType = CommandType.StoredProcedure;
3:  SqlParameter param = cmd.Parameters.Add(paramName, SqlDbType.Int);
4:  param.Value = paramValue;
5:
6:  connection.Open();
7:  cmd.ExecuteNonQuery();
8:  connection.Close();


nakon izvrsenja linije 6, u Performance Monitor-u (pratim otvorene konekcije) otvorena je jedna konekcija (prethodno nije postojala nijedna), a nakon izvrsenja linije 7 postoje dve otvorene konekcije, prvo sam pomislio da SqlCommand (probao sam i sa SqlDataAdapter-om) interno otvara jos jednu konekciju, medjutim, tokom sledeceg potkretanja, desilo mi se da nakon linije 6 odmah postoje otvorene dve konekcije, a komanda sada ne otvara konekcije.

Zaista zanimljivo ponasanje. Ima li neko neko logicno objasnjenje zasto se ovo dogadja?

[ degojs @ 12.07.2004. 19:54 ] @
Možda odmah otvori još jednu konekciju iz pool-a? Ako bi pošli tim putem, možda je upravo stoga drugi put i imao odmah 2 pripremljene i otvorene konekcije. Mada, ne bi trebalo da ih otvori čak i ako su iz pool-a, ako se ne varam.
Ovo je čisto nagađanje.
[ Dragi Tata @ 12.07.2004. 20:06 ] @
OT: Ovaj deo koda može da dovede do resource leak-a:

Code:

connection.Open();
cmd.ExecuteNonQuery(); // Ovo može da baci SqlException ako je row zaključan
connection.Close();


Idealno, trebalo bi konekcije uvek koristiti sa naredbom using, ali mi se čini da connectoin.Dispose(), koju using interno zove ne radi istu stvar kao Close(), pa je možda bolje staviti connection.Close() u finally blok.
[ havramm @ 13.07.2004. 00:07 ] @
Citat:
Dragi Tata
Idealno, trebalo bi konekcije uvek koristiti sa naredbom using, ali mi se čini da connectoin.Dispose(), koju using interno zove ne radi istu stvar kao Close(), pa je možda bolje staviti connection.Close() u finally blok.


Slazem se da je preporuka koristiti using naredbu na mestu, ali sam prethodni primer naveo cisto, kao primer :), medjutim, malo sam pogledao i utvrdio da Dispose() interno poziva Close(), tako da se sa ovim drugim delom bas i ne mogu sloziti, evo i disasembliranog dela za SqlConnection.Dispose(bool) (bez ikakve namere za zloupotrebu i koriscenje disasembliranog koda u komercijalne svrhe)

Code:
protected  void Dispose(bool disposing)
{
    if (disposing)
    {
        ConnectionState state = this._objectState;
        switch (state)
        {
            case ConnectionState.Closed:
            {
                break;
            }
            case ConnectionState.Open:
            {
                this.Close();
                break;
            }
        }
        
        this._constr = null;
    }

    base.Dispose(disposing);
}

A posto SqlConnection.Dispose() interno poziva SqlConnection.Dispose(true) (Dispose pattern), mislim da to dokazuje da i Dispose i Close rade iste stvari. Medjutim to i dalje ne pojasnjava prvopostavljeno pitanje - zasto se otvaraju dve konekcije?
[ mmix @ 13.07.2004. 07:53 ] @
Jesi probao da disasembliraš SqlConnection.Open?
[ havramm @ 13.07.2004. 09:05 ] @
Da, i nisam primetio nista zanimljivo (bar sto bi ukazivalo na navedenu pojavu).
[ dejaniv @ 14.07.2004. 09:33 ] @
Probaj da koristis transakciju (SqlTransaction). Nakon otvaranja konekcije zapocni novu transakciju ovako:

Code:

sqlConnection.Open();
sqlConnection.BeginTransaction();
sqlCommand = new SqlCommand(cmdText, sqlConnection, sqlTransaction);
...            
sqlTransaction.Commit();


Pozdrav!

dejaniv