Me he enfrentado al mismo problema; Tengo que actualizar el monto del crédito, y tengo que obtener el tiempo modificado, junto con los detalles de crédito de DB. Se trata básicamente de
síncrono/atómicamente realizo (ACTUALIZACIÓN A continuación, obtener) en MySQL
He intentado muchas opciones y encontró uno que resolvió mi problema.
1) OPCION_1 SELECT FOR UPDATE
Este es el mantenimiento de la cerradura hasta que la actualización (SYNC de GET ACTUALIZAR), pero necesito bloquear después de la actualización hasta que el GET.
2) OPTION_2 Procedimiento almacenado
procedimiento almacenado no se ejecutará de forma sincrónica como lua Redis, por lo que también necesitamos código de sincronización para realizar eso.
3) option_3 Transacción
he utilizado APP entityManager como a continuación, pensaron que antes de cometer nadie puede actualizar, y antes de cometer voy a conseguir el objeto actualizado junto con la hora de modificación (de DB). Pero no recibí el último objeto. Solo comprometo tengo lo último.
try {
entityManager.getTransaction().begin();
//entityManager.persist(object);
int upsert = entityManager.createNativeQuery(
"update com.bill.Credit c set c.balance = c.balance - ?1
where c.accountId = ?2 and c.balance >= ?1").executeUpdate();
//c.balance >= ? for limit check
Credit newCredit = entityManager.find(Credit.class, "id");
entityManager.refresh(newCredit); //SHOULD GET LATEST BUT NOT
entityManager.getTransaction().commit();
} finally {
entityManager.unwrap(Session.class).close();
}
4) OPTION_4 LOCK resolvió el problema, por lo que antes de la actualización, adquirí el bloqueo; luego después de OBTENER, he liberado el bloqueo.
private Object getLock(final EntityManager entityManager, final String Id){
entityManager.getTransaction().begin();
Object obj_acquire = entityManager.createNativeQuery("SELECT GET_LOCK('" + Id + "', 10)").getSingleResult();
entityManager.getTransaction().commit();
return obj_acquire;
}
private Object releaseLock(final EntityManager entityManager, final String Id){
entityManager.getTransaction().begin();
Object obj_release = entityManager.createNativeQuery("SELECT RELEASE_LOCK('" + Id + "')").getSingleResult();
entityManager.getTransaction().commit();
return obj_release;
}
Se aplica a 'ACTUALIZAR CONJUNTO ... FROM ... WHERE ....'? – Kiquenet