È buona norma usare una singola connessione al database?

5

Il codice in codice PHP su cui sto lavorando ha una classe di utilità che restituisce una connessione al database. L'implementazione è simile a questa:

class Database {
  private static $conn;
  private static $init = false;

  public static function connect() {
    if (!self::$init) {
      $cnf = new Configuration();
      self::$conn = new DatabaseConnection($cnf->get('dbname'), $cnf->get('username'), $cnf->get('password'));
      self::$init = true;
    }

    return self::$conn;
  }
}

Le cose sono state fatte in questo modo per passare apparentemente meno tempo all'apertura delle connessioni, che si verificano su una rete.

Istanziare una singola connessione al database come questa e restituire a tutti i chiamanti una buona pratica di ingegneria del software?

    
posta user2064000 27.06.2016 - 14:15
fonte

4 risposte

4

No.

A meno che tu non sia su un O / S davvero schifoso (o, per essere precisi, la tua libreria ODBC e / o driver / libreria di accesso al database, che possono o meno far parte del proprio O / S), il tuo codice è non effettivamente creando / usando / chiudendo connessioni al database. Sta creando / usando / chiudendo la connessione al database oggetti , che sono un wrapper per le connessioni sottostanti. La connessione sottostante, nel frattempo, viene gestita in un pool.

Quando il codice dell'applicazione "apre" una connessione, stai effettivamente dicendo al sistema di andare a prendere una connessione dal pool, controllarne lo stato e aprire nuove connessioni solo quando necessario.

Quando "chiudi" una connessione, stai effettivamente dicendo al sistema di restituire una connessione al pool per riutilizzarla in seguito, o fino a quando non scade.

È possibile gestire il numero di connessioni, il ciclo di vita, il timeout, ecc. tramite le impostazioni del client ODBC o inserendo i parametri nella stringa di connessione. Ogni stringa di connessione univoca genera un pool di connessioni con tali impostazioni.

Se vuoi veramente esattamente una sola connessione, puoi configurarla in quel modo a livello di piscina - tuttavia questa sarebbe una cattiva idea veramente in un'applicazione web , che a volte ha migliaia di thread.

Lascia che l'O / S sottostante gestisca queste connessioni per te. Sarà molto meglio di qualsiasi codice che scrivi.

    
risposta data 28.06.2016 - 03:11
fonte
1

Is instantiating a single database connection like this and returning that instance to all callers a good software engineering practice?

Questo dipende.

  1. Il codice così com'è non controlla se la connessione è ancora attiva e riconnette se non lo è. Supponendo che questa sia una versione semplificata e che il codice reale esegua tale controllo, quindi:
  2. Finché l'istanza singola di Database viene iniettata in tutti i chiamanti, piuttosto che essere accessibile tramite un localizzatore di servizi, allora è una buona pratica.

Il motivo per cui è buona prassi iniettare una classe singleton come questa è che può essere referenziato tramite un'interfaccia all'interno di quei chiamanti, e quindi una connessione di database fittizio può essere fornita loro durante l'esecuzione dei test unitari.

    
risposta data 27.06.2016 - 14:22
fonte
1

Quello che hai qui sta usando il Pattern Singleton per garantire che tutti i chiamanti ricevano la stessa istanza dell'oggetto di connessione. Suoni efficienti per essere con e, a patto che la tua applicazione sia puramente a thread singolo e mai tenti di fare più di uno [database correlato ] cosa alla volta, probabilmente funzionerà abbastanza bene. Se si tratta di un programma particolarmente lungo (come, ad esempio, un servizio di Windows che funziona 24 ore su 24, 7 giorni su 7), si potrebbe anche considerare l'aggiunta di un codice difensivo in questo metodo per garantire che la connessione sia ancora "valida"; che il database non è stato spento per, diciamo, il servizio di pulizia notturno dall'ultima volta che hai usato la connessione.

I problemi iniziano non appena il tuo programma ottiene qualsiasi tipo di Parallelismo , il tipo di cose che funzionano con un'interfaccia utente guidata dagli eventi sorprendentemente bene.

Ora, la tua connessione al database potrebbe essere in uso, gestendo l'elaborazione di un evento, mentre l'utente fa clic sull'applicazione, facendo sempre più richieste per la tua connessione ora sovraccaricata e bloccata. Ora la tua applicazione è "vista" male, perché non può fare più di una cosa alla volta, cosa che i tuoi utenti potrebbero aspettarsi.

Usando più di una connessione al database, questi casi sono "migliori".

La maggior parte dei sistemi operativi eseguirà automaticamente il pool di connessioni per voi, rendendo quindi l'apertura di una nuova connessione un'operazione light er , ma c'è ancora un overhead limitato. Spingere tutto in modo sequenziale lungo la singola connessione è efficiente; l'avvio di una nuova connessione per ogni operazione non lo è. Devi fare una chiamata di giudizio sul modo in cui la tua applicazione deve andare.

Non è necessario attenersi rigidamente a questa decisione! Il metodo che hai per fornire la tua connessione [Singleton] potrebbe essere modificato in una Fabbrica; se la chiami "ogni tanto", può restituirti l'oggetto di connessione "uno"; se la chiami in "rapida successione" o se rileva che la connessione è "occupata", potrebbe scegliere di restituirne una nuova.

Dipende tutto da quanti problemi ti causano.

    
risposta data 28.06.2016 - 13:10
fonte
1

Sì.

Altre risposte mancano del fatto che PHP è single-threaded e blocking. Generalmente si elabora una richiesta HTTP per processo alla volta. puoi usare più di una connessione alla volta se davvero ne hai bisogno, ma di solito non lo farai. Quindi è perfettamente necessario avere una singola connessione per processo.

Ora se questo era, per esempio, Node.js, allora sì, dovresti usare il pool invece.

    
risposta data 02.07.2016 - 13:04
fonte

Leggi altre domande sui tag