Il giorno lun, 16/05/2011 alle 21.52 +0200, Daniele Varrazzo ha scritto: > On Mon, 16 May 2011 19:37:21 +0200, Marco Fochesato <marco...@libero.it> > wrote: > > > No, niente buchi. > > Allora, spieghiamoci così: > > siamo di fronte ad un gestionale. > > come sempre :) > > > L'utente x parte per compilare un DDT. > > Problemi con le zanzare? > > > L'applicazione "prenota" un id (chiave primaria) per il documento. > > L'utente y parte anche lui per compilare un DDT. > > L'applicazione "prenota" anche per lui un id, lo stesso di quello sopra > > (visto che non è ancora stato chiuso, e potrebbe anche darsi che x > > decida di non chiuderlo e annullare tutto.. (qui è il nocciolo)). > > Il primo che finisce e chiude il ddt, si prende il numero (commit). > > Per il secondo, verrà sollevata una eccezzione e verrà concesso un altro > > id (non mi interessa qui stabilire come). > > Non mi sembra il migliore dei comportamenti: perché far fallire la seconda > transazione quando ci sono almeno diversi modi di farla riuscire? > > E se il secondo finisce prima del primo? Dovrebbe fallire il primo? > > > Quello che mi interessa è la "prenotazione". > > Se vuoi davvero prenotare un record, puoi inserire un record incompleto > oppure tenere una tabella separata delle prenotazioni. Forse anche gli > advisory lock possono essere utili. > > > Io ho bisogno, durante la compilazione del documento, di testare degli > > inserimenti, e vorrei che l'applicazione ragionasse come se l'id fosse > > inserito. Ma se arriva y, che l'id fosse disponibile anche per lui. > > Per fare quello che vuoi tu ha ragione Manlio: usare qualcosa tipo max(id) > + 1 è la soluzione migliore. Manlio però si è dimenticato di dire di > prendere un lock sulla tabella (in pratica gli inserimenti devono essere > serializzati): > > 1) quando il documento viene prenotato: > > a) prendi un lock sulla tabella che conflitti con se stesso, per > esempio "LOCK TABLE blah IN EXCLUSIVE MODE". > b) usa come prossimo id "SELECT max(id) FROM blah" > c) commit sulla connessione, in modo da liberare il lock. > > 2) quando il documento viene salvato: > > a) prendi lo stesso lock sulla stessa tabella > b) prendi lo stesso max > c) se il max è diverso da quanto registrato, tira un eccezione. > > O alternativamente scrivi direttamente il max nel database e aspettati > un'eccezione se c'è una constraint UNIQUE su quel campo. > > Questa è un'implementazione pessima di un lock pessimistico: se uno > comincia un'operazione, qualunque operazione concorrente è destinata a > fallire: perché tu voglia fare questo onestamente mi sfugge. > > La documentazione sui lock > (http://www.postgresql.org/docs/9.1/static/explicit-locking.html) e sul > comando LOCK (http://www.postgresql.org/docs/9.1/static/sql-lock.html) può > esserti utile. > > Lasciare aperta la transazione per tutta la durata dell'edit è qualcosa da > NON fare. > > Ottimo Daniele! Sei stato molto chiaro. Lock table, serializzazioni. Tutte cose che non conosco... Come credo dica il mitico Rocco: l'affare s'ingrossa!!!
Grazie delle dritte ragazzi! Marco _______________________________________________ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python