Mam do czynienia z tym samym problemem; Muszę zaktualizować kwotę kredytu, i muszę uzyskać zmodyfikowany czas, wraz z danymi kredytowymi z DB. To jest w zasadzie
synchronicznie/atomowo wykonać (UPDATE następnie GET) w MySQL
Próbowałem wielu opcji i znaleźć taki, który rozwiązać mój problem.
1) OPTION_1 SELECT FOR UPDATE
ten utrzymuje blokadę aż aktualizacji (synchronicznie z dostać się do aktualizacji), ale muszę zablokować po aktualizacji aż do GET.
2) OPTION_2 składowana procedura
Procedura składowana nie wykona synchronicznie jak Redis Lua, więc tam też musimy kod synchronizacji do wykonywania tego.
3) OPTION_3 transakcja
Używałem WZP EntityManager jak poniżej, pomyślałem, że zanim zdecydują nikt nie może zaktualizować, a przed zatwierdzeniem i otrzyma zaktualizowaną obiektu wraz ze zmodyfikowanym czasie (db). Ale nie dostałem najnowszego obiektu. Dopuść tylko, że mam najnowsze.
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) OPCJA_4 LOCK rozwiązał problem, więc przed aktualizacją uzyskałem zamek; potem po GET zwolniłem blokadę.
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;
}
Dotyczy "UPDATE SET ... FROM ... WHERE ...."? – Kiquenet