2010-09-30 12 views
8

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?

+0

Hola Laird. ¿Tuviste alguna oportunidad de trabajar en esto? ¿Algún hallazgo interesante? –

+0

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. –

+1

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. –

Respuesta

4

Estoy buscando hacer una operación atómica update-if-found-else-insert (una UPSERT) controlada por base de datos.

estoy quizá no responder exactamente toda la cuestión, pero si se desea implementar lo anterior sin ningún tipo de condición de carrera, es necesario un OMI a nivel de tabla LOCK en modo exclusivo (no sólo las filas). No sé si esto se puede hacer con JPA. Tal vez podrías aclarar qué sería aceptable para ti.

2

que se han enfrentado a este tipo de situación y encontramos que:

de bloqueo pesimista, eso significa que el bloqueo de los objetos de transacción comenzar y mantener el bloqueo durante la transacción se realiza por estos 2 PessimisticLockModes: - LockModeType.PESSIMISTIC_READ -> entidad puede ser leído por otras transacciones, pero no se pueden hacer cambios - LockModeType.PESSIMISTIC_WRITE -> entidad no puede ser leído o escrito por otras transacciones

link al artículo

0

Estoy buscando para hacer una operación de actualización -si-encuentra-else-inserto atómica base de datos controlada (un UPSERT).

INSERT .. ON DUPLICATE KEY UPDATE hace eso.