2010-01-19 11 views
18

Ho una tabellaSequenze non influenzate dalle transazioni?

create table testtable(
    testtable_rid serial not null, 
    data integer not null, 
    constraint pk_testtable primary key(testtable_rid) 
); 

Allora supponiamo che faccio questo codice circa 20 volte:

begin; 
insert into testtable (data) values (0); 
rollback; 

e poi fare

begin; 
insert into testtable (data) values (0); 
commit; 

E infine una

select * from testtable 
 
Result: 
row0: testtable_rid=21 | data=0 
Expected result: 
row0: testtable_rid=1 | data=0 

Come si può vedere, le sequenze non sembrano essere influenzate dai rollback delle transazioni. Continuano ad aumentare come se la transazione fosse stata commessa e quindi la riga è stata cancellata. C'è un modo per evitare che le sequenze si comportino in questo modo?

risposta

26

Non sarebbe una buona idea ripristinare le sequenze. Immagina che due transazioni avvengano contemporaneamente, ognuna delle quali utilizza la sequenza per un ID univoco. Se la seconda transazione si impegna e la prima transazione viene ripristinata, il secondo inserisce una riga con "2" mentre il primo riporta la sequenza su "1".

Se tale sequenza viene quindi utilizzata nuovamente, il valore della sequenza diventerà "2" che potrebbe portare a un problema di vincolo univoco.

+2

Se la seconda transazione viene eseguita, questa transazione deve ottenere la sequenza numero 1. Poiché la prima transazione è stata annullata, nessun numero di sequenza sarebbe stato preso per la prima transazione. Certo, PostgreSQL non ha implementato questo, né Oracle, ma non ci sono vincoli concettuali contro il sequenziamento transazionale, solo i vincoli nell'implementazione. – Hartmut

5

No, non c'è. Vedere la nota nella parte inferiore di this page. È una cattiva idea fare qualcosa del genere comunque. Se hai due transazioni in esecuzione contemporaneamente, ciascuna inserendo una riga, vuoi che inseriscano righe con ID diversi.