Newsgroup: it.comp.software.database
Titolo: Singola connessione, molti thread e transazioni su postgresql

Ciao a tutti,
sto usando una applicazione con più thread, che usa postgresql come
database. C'è un thread "worker" con una coda di comandi da eseguire sul
db, e una connessione sempre aperta. Gli altri thread inviano comandi su
questa coda, e quindi non capita mai che i singoli comandi si "mescolino" e
tutto funziona.
Tutto funziona tranne... le transazioni! Infatti l'atomicità che il thread
"worker" riesce a dare è solo a livello di righe. Se mando due "begin
transaction" da due thread separati queste possono ovviamente essere
annidate. A volte ovviamente non posso unire tutti i comandi della
transazione in uno solo, perchè mi serve leggere da programma un valore dal
DB e poi in base a questo decidere cosa fare dopo, tutto in una unica
transazione.
Ho in mente alcune soluzioni ma non so quale sia meglio o se ce ne sono
altre:
1. tenere più di una connessione aperta, e al momento di fare una
transazione passare alla prima connessione libera se c'è, altrimenti
aspettare
2. (caso particolare di 1, o se vogliamo 1 è una generalizzazione di 2)
Mettere un semaforo sulla connessione, e fare le transazioni uno alla
volta. Questo però significa che se un thread perde molto tempo in una
transazione gli altri sono bloccati.
3. aprire le connessioni on-demand, ma questo potrebbe comportare un
notevole overhead
Ci sono svantaggi a tenere sempre aperte molte connessioni con il database?
Si consumano risorse sul server rischiando un DOS? Dovrei piuttosto cercare
di fare tutto sul server con stored procedures fin dove possibile? In ogni
caso come si risolve questo problema?
Ciao e grazie in anticipo
Vincenzo
-- 
Please note that I do not read the e-mail address used in the from field but
I read vincenzo_ml at yahoo dot it
Attenzione: non leggo l'indirizzo di posta usato nel campo from, ma leggo
vincenzo_ml at yahoo dot it

 caso come si risolve questo problema?
Vedi sopra: la soluzione che va per la maggiore è quella di utilizzare 
non una connessione sola ma un pool, dal quale "peschi" volta volta la 
connessione da associare in maniera univoca al client (nel tuo caso al 
thread) e che la rilascerà quando ha finito la sua transazione.
Dal punto di vista dell'efficienza, il pool sarà dimensionato con un 
minimo di connessioni da tenere sempre aperte, e un massimo (inferiore a 
quelle consentite dal DB, ovviamente) che può venire aperto "on demand".
Ma per fare questo lavoro non è il caso che tu reinventi la ruota, ci 
sono già strumenti che fanno la parte "sporca" (vedi JDBC, per esempio).
bye!
-- 
Fabrizio "Hermooz" Ermini

 sono già strumenti che fanno la parte "sporca" (vedi JDBC, per esempio).
L'applicazione è scritta in ocaml, e per ora sto usando solo libpq per
questioni di praticità. Ho visto che esistono proxy  (cioè, ho visto
sqlrelay) che fanno il connection pooling, ma questo vuol dire che la mia
applicazione deve aprire verso il proxy tutte le connessioni che vuole on
demand, e poi sarà il proxy a gestire quali effettivamente debbano essere
riaperte.
Questo vuol dire che usando un proxy ci sarà un piccolo overhead dovuto alle
connessioni al proxy, rispetto a fare tutto nell'applicazione o usando una
libreria, oppure ho capito male io e questo overhead è trascurabile? Tutto
questo tenendo presente che postgresql gira sulla stessa macchina dove gira
l'applicazione.
Ciao e grazie


 sono già strumenti che fanno la parte "sporca" (vedi JDBC, per esempio).
L'applicazione è scritta in ocaml, e per ora sto usando solo libpq per
questioni di praticità. Ho visto che esistono proxy  (cioè, ho visto
sqlrelay) che fanno il connection pooling, ma questo vuol dire che la mia
applicazione deve aprire verso il proxy tutte le connessioni che vuole on
demand, e poi sarà il proxy a gestire quali effettivamente debbano essere
riaperte.
Questo vuol dire che usando un proxy ci sarà un piccolo overhead dovuto alle
connessioni al proxy, rispetto a fare tutto nell'applicazione o usando una
libreria, oppure ho capito male io e questo overhead è trascurabile? Tutto
questo tenendo presente che postgresql gira sulla stessa macchina dove gira
l'applicazione.
Ciao e grazie
Vincenzo


 sono già strumenti che fanno la parte "sporca" (vedi JDBC, per esempio).
L'applicazione è scritta in ocaml, e per ora sto usando solo libpq per
questioni di praticità. Ho visto che esistono proxy  (cioè, ho visto
sqlrelay) che fanno il connection pooling, ma questo vuol dire che la mia
applicazione deve aprire verso il proxy tutte le connessioni che vuole on
demand, e poi sarà il proxy a gestire quali effettivamente debbano essere
riaperte.
Questo vuol dire che usando un proxy ci sarà un piccolo overhead dovuto alle
connessioni al proxy, rispetto a fare tutto nell'applicazione o usando una
libreria, oppure ho capito male io e questo overhead è trascurabile? Tutto
questo tenendo presente che postgresql gira sulla stessa macchina dove gira
l'applicazione.
Ciao e grazie
Vincenzo


 sono già strumenti che fanno la parte "sporca" (vedi JDBC, per esempio).
L'applicazione è scritta in ocaml, e per ora sto usando solo libpq per
questioni di praticità. Ho visto che esistono proxy  (cioè, ho visto
sqlrelay) che fanno il connection pooling, ma questo vuol dire che la mia
applicazione deve aprire verso il proxy tutte le connessioni che vuole on
demand, e poi sarà il proxy a gestire quali effettivamente debbano essere
riaperte.
Questo vuol dire che usando un proxy ci sarà un piccolo overhead dovuto alle
connessioni al proxy, rispetto a fare tutto nell'applicazione o usando una
libreria, oppure ho capito male io e questo overhead è trascurabile? Tutto
questo tenendo presente che postgresql gira sulla stessa macchina dove gira
l'applicazione.
Ciao e grazie
Vincenzo


 l'applicazione.
Diciamo che usando il C.P. (che tu te lo faccia da solo o che lo faccia 
il proxy mi sa che alla fin fine è uguale, cambia solo chi fa il lavoro, 
ma il lavoro da fare quello è...) vai a cercare un trade-off: da una 
parte cerchi di avere sempre almeno qualche connessione già aperta, 
dall'altra cerchi di non intasare le risorse della macchina aprendo più 
connessioni di quelle che ti servono...
-- 
Fabrizio "Hermooz" Ermini