[Db] contatore server side

Domenico L. domenico.lorusso a pleiade.it
Gio 1 Feb 2007 10:53:51 CET


Francesco F ha scritto:
> Difatti con una function dà errore, con una SP no (misteri di mysql)
Mah... il discorso funciton, siccome lo aveva anche Oracle, supponevo 
fosse legato ad un qualche tipo di implementazione che mi sfuggiva, che 
ne so: le function possono essere usate dentro le query quindi devono 
avere tempi molto brevi, oppure non hai la sicurezza che la funzione non 
acceda alla stessa tabella che stai manipolando rischiando un deadlock...

Però non ha senso che richiamando un una procedura che modifica la 
tabela del trigger che ha richiamato la procedura non si incastri. Ci si 
ingarbuglia solo a dirlo!

>
>> Per ovviare e avere un'assoluta sequenzialità occorre per forza avere 
>> un primo inserimento di un codice dummy e successivamente il codice 
>> sequenziale corretto. :-)
> L' (if(isnull(max(id)), 0, max(id)) + 1) non è sufficiente?
beh dunque avendo il lock a livello di riga:

tempo 0 utente A fa una insert
tempo 1 utente B fa una insert

tempo 2 processo di A,  ottiene il numero massimo e ci aggiunge 1
tempo 3 processo di B,  fa la stessa cosa

tempo 4 processo A inserisce il record
tempo 5 processo B inserisce il record


morale B va in errore perché la primary key è duplicata

Una soluzione è quella di ottenere il valore e (con un isolation level 
molto elevato) di inserire subito il record.

Ora con i lock a livello di tabella questo problema non c'è, perché come 
A inizia, B dovrebbe rimanere in attesa che finisca A

Con gli innodb, dovresti richiedere un lock di tipo write su tutta la 
tabella (non so la sintassi purtroppo, ma dovrebbe riguardare 
l'isolation level), in questo modo tutti possono leggere ma solo tu 
scrivi, il problema è che blocchi anche gli update.

Se invece utilizzi una tabella di appoggio da cui ricavare solo l'id 
(può essere unica per tutte le tabelle e per tutti i casi) la cosa 
potrebbe migliorare perché già solo con un lock a livello di riga 
dovresti essere sicuro di non creare casini:

trigger before
   
    recupero nextId (se non c'è il record lo inserisco con valore 0) 
esiste il costrutto *select ... for update* 
http://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html
   
trigger after
    update di nextId in tabella appoggio



ciauz



-- 
Domenico L.                             icq: 645 44 861

per stupire mezz'ora basta un libro di storia,
io cercai di imparare la Treccani a memoria... [F.d.A.]



Maggiori informazioni sulla lista Db