2012-04-06 9 views
8

Ho provato questo con MySQL Server 5.5:MySQL lettura ripetibile e perso aggiornamento/letture fantasma

1) garantito che livello di isolamento è REPEATABLE_READ

2) iniziato shell-1, ha iniziato una transazione in esso, poi leggere un valore tramite seleziona

3) iniziato shell-2, ha iniziato una transazione in esso, quindi leggere lo stesso valore attraverso selezionare

4) nel guscio 1, aggiornato il valore al valore + 1 e impegnato

5) in guscio-2, aggiornato il valore al valore + 1 e impegna

Il valore perso uno dei suoi aggiornamenti ed è stato incrementato solo di 1.

Ora, a quanto mi risulta, usi RR blocchi di lettura condivisi e blocchi di scrittura esclusivi, il che significa che nei precedenti paragrafi 4 e 5, le transazioni dovrebbero essere bloccate, ma ciò non è accaduto.

Quindi la mia comprensione di RR è errata, o MySQL implementa RR in un modo diverso. Quindi, cos'è?

EDIT: tramite un esperimento simile, ha anche confermato che una transazione RR (t1) non vede le righe inserite nella stessa tabella da un'altra transazione RR (t2), se fa un'altra selezione su quella tabella anche dopo che t2 ha eseguito il commit e prima di t1 impegnarsi. (Questo è il collegamento a questo esperimento: http://www.databasejournal.com/features/mysql/article.php/3393161/MySQL-Transactions-Part-II---Transaction-Isolation-Levels.htm)

Significa che anche l'RR di MySQL si occupa delle letture fantasma?

+0

Hai provato transazioni serializzabili? http://dev.mysql.com/doc/refman/5.1/en/set-transaction.html#isolevel_serializable – biziclop

+0

Sì, e sembra che MySQL serializable usi blocchi di lettura condivisi e blocchi di scrittura esclusivi, e quindi dà un deadlock nel sopra il caso. Quindi sono molto confuso, perché ecco cosa dice il libro "JP with Hibernate": "Un sistema operativo in modalità di isolamento di lettura ripetibile non consente né letture irrilevanti né letture sporche. Possono verificarsi letture fantasma Operazioni di scrittura transazioni di blocco (ma non altre transazioni di lettura) e le transazioni di scrittura bloccano tutte le altre transazioni. " (pagina 456) – shrini1000

risposta

6

MySQL non conforme a Ripetibile Leggere davvero. Puoi forzarlo a fare usando il livello di isolamento serializzabile o mettendo un FOR UPDATE dopo averlo selezionato (guarda l'esempio sotto). Quindi il comportamento desiderato sarà raggiunto. Per quanto riguarda letture fantasma, MySQL è in realtà più rigorosa del necessario ...

SELECT value FROM table WHERE id = 7 FOR UPDATE; 
+0

thx! Potresti pl. citare un riferimento per questo, quindi posso accettarlo come risposta? – shrini1000

+4

http://www.cs.umb.edu/~poneil/iso.pdf afferma che gli aggiornamenti persi non sono possibili nella lettura ripetibile. Puoi trovare il riepilogo sull'ultima pagina e la discussione su quella specifica anomalia da qualche parte nel mezzo (cerca solo "aggiornamento perso"). Non posso darti più riferimenti, spero che per ora sia sufficiente. – Argeman

+0

Solo per essere sicuri: gli aggiornamenti persi sono infatti possibili quando si utilizza InnoDB con lettura ripetibile a causa della loro implementazione non conforme. È giusto? – Basti

Problemi correlati