Ho affrontato lo stesso problema; Devo aggiornare l'ammontare del credito, e devo ottenere il tempo modificato, insieme con i dettagli del credito da DB. Si tratta essenzialmente di
contemporaneamente/atomicamente compio (UPDATE poi GET) in MYSQL
Ho provato molte opzioni e trovato uno che ha risolto il mio problema.
1) option_1 SELECT PER AGGIORNAMENTO
Questa è mantenere il blocco fino aggiornamento (SYNC da GET a UPDATE), ma ho bisogno di bloccare dopo l'aggiornamento fino al GET.
2) OPTION_2 stored procedure
stored procedure non verrà eseguito in modo sincrono come Redis lua, Quindi non abbiamo bisogno anche del codice di sincronizzazione per eseguire questo.
3) OPTION_3 Transaction
ho usato JPA entityManager come qui di seguito, pensavano che prima di commettere nessuno può aggiornare, e prima di commettere mi metterò l'oggetto aggiornato con il tempo modificato (da DB). Ma non ho ricevuto l'ultimo oggetto. Solo commit ho ottenuto l'ultimo.
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 ha risolto il problema, quindi prima dell'aggiornamento ho acquisito il blocco; quindi dopo aver ottenuto il blocco ho rilasciato.
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;
}
fonte
2017-07-12 17:38:45
Si applica a "AGGIORNAMENTO IMPOSTATO ... DA ... DOVE ....'? – Kiquenet