Mysql
 sql >> Baza danych >  >> RDS >> Mysql

MySQL:transakcje a tabele blokowania

Blokowanie tabel uniemożliwia innym użytkownikom bazy danych wpływanie na zablokowane wiersze/tabele. Ale blokady same w sobie NIE zapewnią spójnego stanu logiki.

Pomyśl o systemie bankowym. Kiedy płacisz rachunek online, są co najmniej dwa konta objęte transakcją:Twoje konto, z którego pobierane są pieniądze. Oraz konto odbiorcy, na które przelewane są pieniądze. I konto w banku, na które z radością wpłaci wszystkie opłaty serwisowe pobierane od transakcji. Biorąc pod uwagę (jak wszyscy wiedzą w dzisiejszych czasach), że banki są wyjątkowo głupie, powiedzmy, że ich system działa tak:

$balance = "GET BALANCE FROM your ACCOUNT";
if ($balance < $amount_being_paid) {
    charge_huge_overdraft_fees();
}
$balance = $balance - $amount_being paid;
UPDATE your ACCOUNT SET BALANCE = $balance;

$balance = "GET BALANCE FROM receiver ACCOUNT"
charge_insane_transaction_fee();
$balance = $balance + $amount_being_paid
UPDATE receiver ACCOUNT SET BALANCE = $balance

Teraz, bez blokad i transakcji, system ten jest podatny na różne warunki wyścigu, z których największym jest wielokrotne dokonywanie płatności na Twoim koncie lub na koncie odbiorcy równolegle. Podczas gdy Twój kod ma odzyskane saldo i wykonuje funkcję huge_overdraft_fees() i tak dalej, jest całkowicie możliwe, że jakaś inna płatność będzie równolegle uruchamiać ten sam typ kodu. Odzyskają twoje saldo (powiedzmy 100 dolarów), wykonają swoje transakcje (wyjmą 20 dolarów, które płacisz, i 30 dolarów, którymi cię wkręcają), a teraz obie ścieżki kodu mają dwa różne salda:80 dolarów i 70 dolarów. W zależności od tego, które z nich zakończy się jako ostatnie, otrzymasz jedno z tych dwóch sald na swoim koncie, zamiast 50 USD, które powinieneś mieć (100 USD - 20 USD - 30 USD). W tym przypadku „błąd banku na twoją korzyść”.

Załóżmy, że używasz zamków. Twoja płatność za rachunek (20 USD) trafia jako pierwsza, więc wygrywa i blokuje rekord Twojego konta. Teraz masz wyłączne użycie i możesz odjąć 20 USD od salda i w spokoju odpisać nowe saldo ... a Twoje konto zakończy się z 80 USD zgodnie z oczekiwaniami. Ale... ohh... Próbujesz zaktualizować konto odbiorcy i jest ono zablokowane i zablokowane dłużej niż pozwala na to kod, limit czasu transakcji... Mamy do czynienia z głupimi bankami, więc zamiast poprawnego błędu obsługi, kod po prostu ściąga exit() , a twoje 20 dolarów znika w kłębku elektronów. Teraz tracisz 20 dolarów i nadal jesteś winien 20 dolarów odbiorcy, a twój telefon zostaje przejęty.

Więc... wprowadź transakcje. Rozpoczynasz transakcję, obciążasz swoje konto 20 zł, próbujesz zasilić odbiorcę kwotą 20 zł... i znowu coś wybucha. Ale tym razem zamiast exit() , kod może po prostu wykonać rollback , i puf, twoje 20 $ zostanie magicznie dodane z powrotem do twojego konta.

W końcu sprowadza się to do tego:

Blokady uniemożliwiają innym ingerowanie w rekordy bazy danych, z którymi masz do czynienia. Transakcje sprawiają, że wszelkie „późniejsze” błędy nie zakłócają „wcześniejszych” czynności. Żaden sam nie może zagwarantować, że wszystko w końcu ułoży się dobrze. Ale razem robią.

w jutrzejszej lekcji:Radość impasów.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PDO MySQL:użyć PDO::ATTR_EMULATE_PREPARES czy nie?

  2. Obciąć wszystkie tabele w bazie danych MySQL w jednym poleceniu?

  3. Jak przechowywać datę i godzinę w MySQL z informacją o strefie czasowej?

  4. Jak połączyć się z wieloma bazami danych MySQL na jednej stronie internetowej?

  5. Wskazówki dotyczące aktualizacji klastra Percona XtraDB do wersji 8.0