Czy transakcja może odrzucic kolejne transakcji

Czy transakcja może odrzucic kolejne transakcji
RK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 49
0

Zastanawiam się jak zapobiec nastepujacej sytuacji:
Dwoch klientow uruchamia swoje transakcje update do pola bazy. Powiedzmy, ze jego wartosc wynosila 10 i oboje chca zwiekszyc ja o 2. Tworzy sie jak rozumiem kolejka transakcji z ktorych pierwsza zmienia wartosc pola na 12. Druga czeka az pierwsza sie zakonczy i po tym fakcie zmienia wartosc pola + 2 wiec ostatecznie otrzymujemy 14.
Czy jest jakiś mechanizm umożliwiający się zabezpieczenie się przed taką sytuacją?

S4
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1268
1

A możesz powiedzieć jaki rzeczywisty problem chcesz tym rozwiązać?

woolfik
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1618
4

Możesz przyblokować rekord klauzulą FOR UPDATE wtedy inna transakcja Ci go nie zmieni póki swojej nie zatwierdzisz.
Tu masz fajny opis co i jak
FOR UPDATE NOWAIT

RA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 376
0

To tak nie działa, nie napisałeś w jaki sposób sprawdzasz jaka jest wartość i jak dodajesz 2.

RK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 49
0

2 użytkownikow z 2 roznych stacji w swoich widokach widzi ceny arykulów. Pierwszy ma prawo admina i uruchamia transakcje aktualizujaca cene 1 mln towarow o +2 zł. Drugi wszedl w formatke edycji danych o towarze zanim pierwsza transakcja sie rozpoczela, zwiekszyl cene o +2 i kliknal Zapisz ale juz uruchomila sie transakcja nr 1. Zapis czeka az transakcja 1 sie zakonczy i nstepnie zwiekasz cene arykulu o +2.
Chce uniknac zwiekszenia ceny tego jednego artykulu o 4.

YA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2399
1

Jeśli dwie transakcje walą czymś w stylu: update blah set a=a+2;, to możesz spróbować ustawić poziom izolacji transakcji na serializable. Wówczas jedna z sesji powinna się wywalić.

Minusem ustawienia serializable może być to, że wywalą się z innego powodu ;-)

Na moje oko problemem może być sposób w jaki generujesz transakcje, a nie to w jaki sposób silnik obsługuje transakcje.

RA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 376
3

Jeżeli chcesz uniknąć nadpisania (lub jak tutaj aktualizacji danych które zostały już w innej sesji zmienione) to stosuje się do tego optimistic locking.
Inaczej przy każdym pobraniu danych musiałbyś robić select for update i tym sposobem zablokowałbyś całą bazę.

woolfik
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1618
2

W takim momencie najlepszym rozwiązaniem jest właśnie for update nowait bo druga transakcja od razu dostanie wyjątek, że jest akcja "przecena" na pierwszej transakcji. W większości systemów i mechanizmów masowej przeceny uruchamia się coś na wzór trybu serwisowego aby właśnie nie dochodziło do takich rzeczy.

Marcin.Miga
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2794
3

Problem jest raczej z dupy. Jeszcze nigdzie nie spotkałem się z klawiszem "zwiększ cenę o 2 PLN". Jak już to jest pole tekstowe do wpisania, gdzie user zmienia z 10 na 12.
I wtedy do bazy idzie update: UPDATE cena=12 WHERE id=... a nie UPDATE cena=cena+2 WHERE id=...

abrakadaber
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 6610
4

poczytaj o blokowaniu pesymistycznym i optymistycznym, rozjaśni Ci sytuację i pomoże na przyszłość

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.