[Db] contatore server side
Domenico L.
domenico.lorusso a pleiade.it
Mer 3 Gen 2007 13:05:15 CET
Marcello Vezzelli ha scritto:
> Domenico L. wrote:
>>
>>> Ma fare una lock table in questi casi serve a qualcosa o è una
>>> bestialità?
>> No mysql 5 ha il lock a livello di riga quindi tutto bene.
>
>
>>
>> Mi lascia un po' da pensare il concetto che è possibile cancellare
>> l'ultima, in un ambiente concorrente il concetto di ultima è una cosa
>> che non ci si può permettere di avere.
>
> Supponiamo che la transazione che si occupa di cancellare l'ultima
> fattura faccia una lock table... consideriamo la cancellazione
> dell'ultima fattura un evento raro e va bene gestirlo in questo modo.
>
> Se qualcuno posta durante la cancellazione, si becca un errore del
> tipo "table locked" e fa il rollback. Corretto?
> Gestendo la cosa lato applicativo, si aspetta un attimino e si
> riprova. Parliamo veramente di centesimi di secondo, ma la questione è
> concettuale quindi vale la pena discuterne... supponiamo che la
> cancellazione di un record duri un tempo lungo a sufficienza.
> Finita la transazione della cancellazione, il nuovo post otterrà
> correttamente il valore numfatt facendo una select dell'ultimo numero
> di fattura in tabella incrementato di uno.
> Domandone: da quanto ho letto, l'esecuzione del trigger BEFORE INSERT
> è atomica su ogni tabella, corretto? Ovvero il trigger gira fuori da
> qualsiasi transazione, quindi sono tutti sequenziali.
uhm.... credo tu abbia capito ma hai scritto il contrario....
allora il dml come tu ben sai deve essere atomico (ACID)
Ora fare una insert (o update o delete) produce l'esecuzione atomica di:
before update (con vincoli sull'accesso alla tabella)
inserimento
validazione constraints (salvo differimento)
after update
Da questa osservazione possiamo iniziare a delineare un soluzione:
tabella Sequenza (id autorincremet ciclico) unica per tutto il db
Before INSERT:
insert into Sequenza return_isertd_id into id;
set new:numfat=id;
insert
After Insert:
delete from Sequenza where id=new.numfat;
begin
select id+1 into xId
from fat_seq
where anno=new.anno for update; #se esiste
update fat_seq
set id = xId
where anno=new.anno;
exception
when no_data_found then
insert into fat_Seq values(new.anno, 1);
xId = 1;
when others then raise;
end;
update fattura
set numfat=xId
where anno=new.anno and numfat=new.numfatt
and ....
;
Più o meno il codice purtroppo non sono sicuro sia corretto, però la
logica dovrebbe esserci :-)
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