He leído this article on JPA concurrency, pero o bien soy demasiado grueso o no es lo suficientemente explícito.¿LockModeType.PESSIMISTIC_WRITE es suficiente para un UPSERT en JPA?
Estoy buscando hacer una operación atómica update-if-found-else-insert atómica controlada por base de datos (un UPSERT
).
Se ve a mi pobre cerebro lento que puedo - dentro de una transacción, por supuesto, - ejecutar una consulta con nombre con un modo de bloqueo de PESSIMISTIC_WRITE
, ver si devuelve ningún resultado, y luego o bien un persist()
o un update()
después.
Lo que no tengo claro son las diferencias entre realizar esta operación con un candado PESSIMISTIC_WRITE
frente a un candado PESSIMISTIC_READ
. He leído las oraciones: entiendo que PESSIMISTIC_READ
está destinado a evitar lecturas no repetibles, y PESSIMISTIC_WRITE
es ... bueno, tal vez no entiendo tan bien :-) - pero debajo es solo un SQL SELECT FOR UPDATE
, ¿sí? ¿En ambos casos?
Hola Laird. ¿Tuviste alguna oportunidad de trabajar en esto? ¿Algún hallazgo interesante? –
No he tenido el tiempo para cavar y ver qué está pasando realmente. Puse un bloqueo PESSIMISTIC_WRITE porque el artículo de simultaneidad parecía intentar insinuar que esto me permitiría hacer un UPSERT sin condición de carrera. Tangente: un UPSERT parece una operación tan increíblemente común que DEBE haber una forma de hacerlo en JPA. –
Tengo la sensación de que echo de menos algo aquí. ¿Por qué no puedes hacer un find() + insert() si es necesario? Supongo que la transacción garantizará la atomicidad. Creo que el tipo de bloqueo es menos importante, incluso podrías usar bloqueo + control de versiones optimistas. Supongo que las entradas duplicadas están protegidas con una restricción única. –