PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

devo attivare il pool di istruzioni c3p0?

Non ricordo a caso se Hibernate archivia effettivamente le istanze PreparedStatement o fa affidamento sul provider di connessione per riutilizzarle. (Una rapida scansione di BatcherImpl suggerisce di riutilizzare l'ultimo PreparedStatement se si esegue lo stesso SQL più volte di seguito)

Penso che il punto che la documentazione c3p0 sta cercando di fare è che per molti driver JDBC, una PreparedStatement non è utile:alcuni driver finiranno semplicemente per unire i parametri sul lato client e quindi passare comunque l'istruzione SQL compilata al database . Per questi driver, le PreparedStatement non sono affatto un vantaggio e ogni sforzo per riutilizzarle è sprecato. (Le domande frequenti su Postgresql JDBC affermano che questo era il caso di Postgresql prima del protocollo server versione 3 e nella documentazione sono presenti informazioni più dettagliate).

Per i driver che gestiscono in modo utile PreparedStatement, è ancora probabilmente necessario riutilizzare effettivamente le istanze PreparedStatement per ottenere qualsiasi vantaggio. Ad esempio se il conducente implementa:

  • Connection.prepareStatement(sql) - crea un'istruzione lato server
  • PreparedStatement.execute(..) etc - esegui quell'istruzione lato server
  • PreparedStatement.close() - dealloca l'istruzione lato server

Detto questo, se l'applicazione apre sempre un'istruzione preparata, la esegue una volta e poi la chiude di nuovo, c'è ancora nessun beneficio; in effetti, potrebbe essere peggio poiché ora ci sono potenzialmente più viaggi di andata e ritorno. Quindi l'applicazione deve rimanere attaccata alle istanze PreparedStatement. Naturalmente, questo porta a un altro problema:se l'applicazione si blocca su troppi e ogni istruzione lato server consuma alcune risorse, ciò può portare a problemi lato server. Nel caso in cui qualcuno utilizzi direttamente JDBC, questo potrebbe essere gestito manualmente:alcune istruzioni sono note per essere riutilizzabili e quindi vengono preparate; alcuni non lo sono e usano invece solo istanze di Statement transitorie. (Questo sta saltando l'altro vantaggio delle istruzioni preparate:gestire l'escape degli argomenti)

Quindi questo è il motivo per cui c3p0 e altri pool di connessioni hanno anche preparato cache di istruzioni:consente al codice dell'applicazione di evitare di gestire tutto questo. Le istruzioni sono generalmente conservate in un pool LRU limitato, quindi le istruzioni comuni riutilizzano un'istanza PreparedStatement.

Gli ultimi pezzi del puzzle sono che i driver JDBC potrebbero decidere di essere intelligenti e farlo; e i server stessi possono anche decidere di essere intelligenti e rilevare un cliente che invia una dichiarazione strutturalmente simile a una precedente.

Dato che Hibernate stesso non mantiene una cache di istanze PreparedStatement, è necessario che c3p0 lo faccia per trarne vantaggio. (Che dovrebbe essere un sovraccarico ridotto per le istruzioni comuni a causa del riutilizzo dei piani memorizzati nella cache). Se c3p0 non memorizza nella cache le istruzioni preparate, il driver vedrà semplicemente l'applicazione preparare un'istruzione, eseguirla e quindi chiuderla di nuovo. Sembra che il driver JDBC abbia un'impostazione di "soglia" per evitare il sovraccarico del server di preparazione/esecuzione nel caso in cui l'applicazione lo faccia sempre. Quindi, sì, è necessario che c3p0 esegua la memorizzazione nella cache delle istruzioni.

Spero di esserti stato d'aiuto, mi dispiace che sia un po' prolisso. La risposta è .