2010-09-30 15 views
8

Ho letto this article on JPA concurrency, ma o sono troppo spesso o non è abbastanza esplicito.LockModeType.PESSIMISTIC_WRITE è sufficiente per un UPSERT in JPA?

Sto cercando di eseguire un'operazione di aggiornamento atomico controllata da database (se esistente) (un numero UPSERT).

E Sembra al mio povero cervello lento che posso - all'interno di una transazione, naturalmente - eseguire una query di nome con una modalità di blocco di PESSIMISTIC_WRITE, vedere se restituisce alcun risultato, e poi o un persist() o un update() in seguito.

Quello su cui non sono chiaro sono le differenze tra l'esecuzione di questa operazione con un blocco PESSIMISTIC_WRITE e un blocco PESSIMISTIC_READ. Ho letto le frasi - ho capito che lo PESSIMISTIC_READ ha lo scopo di prevenire letture non ripetibili, e PESSIMISTIC_WRITE è ... beh, forse non lo capisco così bene :-) - ma sotto è solo un SQL SELECT FOR UPDATE, sì? In entrambi i casi?

+0

Ciao Laird. Hai avuto l'opportunità di lavorare su questo? Qualche scoperta interessante? –

+0

Non ho avuto il tempo di scavare e vedere cosa sta succedendo. Ho inserito un blocco PESSIMISTIC_WRITE perché sembrava che l'articolo sulla concorrenza stesse cercando di insinuare che questo mi avrebbe permesso di fare un UPSERT senza condizioni di gara. Tangente: un UPSERT sembra un'operazione così incredibilmente comune che DEVE esserci un modo per farlo in JPA. –

+1

Ho la sensazione che mi manchi qualcosa qui. Perché non puoi semplicemente fare un find() + insert() se necessario. Suppongo che la transazione garantisca l'atomicità? Penso che il tipo di blocco sia meno importante, potresti addirittura utilizzare il blocco ottimistico + il controllo delle versioni? Suppongo che le voci duplicate siano protette utilizzando un vincolo univoco. –

risposta

4

Sto cercando un'operazione di aggiornamento atomico controllata da database (se trovata) (un UPSERT).

sto forse non risponde esattamente l'intera questione, ma se si desidera implementare quanto sopra, senza alcuna condizione di competizione, è necessario un IMO a livello di tabella BLOCCO in modalità esclusiva (non solo le righe). Non so se questo può essere fatto con JPA. Forse potresti chiarire cosa sarebbe accettabile per te.

2

ho affrontato questo tipo di situazione e ho trovato questo:

blocco pessimistico, questo significa bloccaggio di oggetti sul transazioni iniziare e mantenere il blocco durante la transazione è fatto da questi 2 PessimisticLockModes: - LockModeType.PESSIMISTIC_READ -> entità può essere letto da altre operazioni, ma nessun cambiamento può essere fatto - LockModeType.PESSIMISTIC_WRITE -> entità non può essere letto o scritto da altre operazioni

link l'articolo