ORM Doctrine, souběžný přístup
- Relapse
- Člen | 34
Dobrý den,
prosím vás, řeší nějak doctrine souběžný přístup k položkám
v databázi?
Mám konkrétní příklad:
$product = $this->products->getProduct($id);
$product->quantity -= $orderQuantity;
$this->em->flush();
Jednoduše odečítám zásoby ze skladu.
Může dojít k situaci, kdy načtu z databáze objekt ‚Product‘
s hodnotou parametru ‚quantity = 100‘.
Ale než se její změna uloží ‚em->flush()‘, někdo jiný odečte a
uloží např. 10. Takže správná hodnota v databázi ted bude 90, ale já
mám načteno 100 a od této hodnoty budu odečítat.
Musím si takovou situaci ošetřit sám, nebo se o to nějakým způsobem stará doctrine?
Děkuji za pomoc.
- Relapse
- Člen | 34
Zatím to mám udělané následovně:
$this->em->getConnection()->beginTransaction()
try {
//pesimistické zamykání
//znemožní konkurenčním procesům číst a aktualizovat tyto záznamy
$product = $this->products->getProduct($id, DoctrineDBALLockMode::PESSIMISTIC_WRITE);
$product->quantity -= $orderQuantity;
$this->em->flush();
$this->em->getConnection()->commit();
} catch (Exception $e) {
$this->em->getConnection()->rollback();
$this->em->close();
throw $e;
}
Zámek se odemkne po úspěšném volání COMMIT()?.
Jednoduše zamknu záznam Product, změním co potřebuji a odemknu, ať si ho může měnit zase někdo jiný.
V doctrine s tímto pracuji poprvní, tak mi prosím vás řekněte, jestli
jsem se vydal správným směrem.
Děkuji
Editoval Relapse (9. 2. 2015 10:49)
- llook
- Člen | 407
Vydal jsi se správným směrem. Doctrine ORM sama od sebe do transakce uzavírá jenom flush.
Případně to zabal do transactional
:
$this->em->getConnection()->transactional(function () {
$product = $this->products->getProduct($id, DoctrineDBALLockMode::PESSIMISTIC_WRITE);
$product->quantity -= $orderQuantity;
$this->em->flush();
});