Nuova connessione vs nuova connessione

1

Questa domanda potrebbe essere stata chiesta in precedenza, ma non riesco a trovarla.

Quindi ecco:

Sto scrivendo un programma che si collega a diversi database (uno alla volta). Al momento utilizza OleDbConnection , ma a un certo punto verrà modificato in SqlConnection .

Devo creare e aprire una nuova connessione ogni volta , o semplicemente chiudere la connessione esistente, assegnare una nuova connectiontring e riaprirla.

So che entrambe le soluzioni funzionano, ma perché preferirei l'una rispetto all'altra.

Per completezza, ecco l'implementazione:

Codice eseguito quando si modifica il database.

var connection = new OleDbConnection(connectionString);
HasConnection = true;
ConnectionEstablished(this, new ConnectionArgs<OleDbConnection>(connection));

Codice che agisce su quella modifica

public async Task ExecuteAsync(string query, Func<IDataReader, Task> onExecute, params DataParameter[] parameters)
{
    using(var command = builder.BuildCommand(query))
    {
        foreach(var parameter in parameters)
            command.AddParameter(parameter);
        if(!connection.IsOpen)
            connection.Open();
        await command.ExecuteAsync(onExecute);
    }
}

private void OnConnectionEstablished(object sender, ConnectionArgs<IConnection> e)
{
    this.connection = e.Connection;
}

C'è un modo per usare l'istruzione using e conservare ancora questa struttura?

    
posta Chris Wohlert 21.08.2017 - 09:26
fonte

1 risposta

3

L'approccio consigliato è di aprire ogni volta una nuova connessione con l'istruzione using .

using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
        // Do work here; connection closed on following line.
    }

Il motivo per preferire questo approccio è che garantisce che la connessione verrà chiusa dopo l'uso.

Tuttavia, sembra che non sia performante, tranne per il fatto che esiste una funzionalità dell'oggetto SqlConnection chiamata "Pool di connessioni".

To deploy high-performance applications, you must use connection pooling. When you use the .NET Framework Data Provider for SQL Server, you do not have to enable connection pooling because the provider manages this automatically, although you can modify some settings. For more information, see SQL Server Connection Pooling (ADO.NET).

link

Connection pooling reduces the number of times that new connections must be opened. The pooler maintains ownership of the physical connection. It manages connections by keeping alive a set of active connections for each given connection configuration. Whenever a user calls Open on a connection, the pooler looks for an available connection in the pool.

link

Sembra che ODBCConnection sia leggermente diverso, ma ha ancora un'opzione di pool di connessioni.

Oggetto: domanda aggiornata

Quindi c'è il modo ovvio di usare semplicemente la stringa di connessione dalla connessione passata per fare "nuove" connessioni con l'uso. Ma probabilmente sarebbe meglio refactoring.

Il tuo codice corrente ha una condizione di competizione sull'istruzione aperta e non viene mostrata nessuna chiusura.

Tuttavia, viene utilizzato il pool di connessioni? non sono sicuro. Chiami solo una volta aperta, quindi penso che tutto verrà eseguito sulla stessa connessione db senza che il codice di pool abbia bisogno di fare qualcosa.

Questo elimina la condizione di gara su Apri, assicura che i comandi possano essere completati senza che la connessione sottostante si chiuda o cambi su di essi e garantisce che tutte le connessioni siano chiuse;

public async Task ExecuteAsync(string query, Func<IDataReader, Task> onExecute, params DataParameter[] parameters)
{
    using(var conn = new SqlConnection(this.connstr))
    using(var command = builder.BuildCommand(query, conn))
    {
        conn.Open();
        foreach(var parameter in parameters) 
        {
            command.AddParameter(parameter);
        }
        await command.ExecuteAsync(onExecute);
    }
}

private void OnConnectionEstablished(object sender, ConnectionArgs<IConnection> e)
{
    this.connstr = e.Connection.ConnectionString ;
}
    
risposta data 21.08.2017 - 11:17
fonte

Leggi altre domande sui tag