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

Blokowanie poziomu wiersza w Mysql

Zamiast FOR UPDATE użyj LOCK IN SHARE MODE . FOR UPDATE uniemożliwia innym transakcjom odczytanie wiersza. LOCK IN SHARE MODE umożliwia odczyt, ale uniemożliwia aktualizację.

Odniesienie:Podręcznik MySQL

------ sesja 1

START TRANSACTION;
SELECT * FROM test WHERE t=1 LOCK IN SHARE MODE;
UPDATE test SET NAME='irfandd' WHERE t=2;
COMMIT;

----- sesja 2 (która nie jest już blokowana :) )

START TRANSACTION;
UPDATE test SET NAME='irfandd' WHERE t=4;
COMMIT;

Aktualizacja:

Zdając sobie sprawę, że tabela nie ma indeksu na t , mam następujące wyjaśnienie:

Po pierwsze, transakcja T1 blokuje wiersz 1 w SELECT * FROM test WHERE t=1 FOR UPDATE

Następnie transakcja T2 próbuje wykonać UPDATE test SET NAME='irfandd' WHERE t=4 . Aby dowiedzieć się, których wierszy dotyczy problem, musi przeskanować wszystkie wiersze, w tym wiersz 1 . Ale to jest zablokowane, więc T2 musi poczekać, aż T1 się zakończy. Jeśli istnieje jakikolwiek indeks, WHERE t=4 może użyć indeksu, aby zdecydować, czy wiersz 1 zawiera t=4 czy nie, więc nie trzeba czekać.

Opcja 1: dodaj indeks na test.t aby Twoja aktualizacja mogła z niego korzystać.

Opcja 2: użyj LOCK IN SHARE MODE , który jest przeznaczony do nakładania tylko blokady odczytu. Niestety ta opcja powoduje zakleszczenie. Co ciekawe, transakcja T2 jest wykonywana (aktualizacja wiersza 4), a T1 kończy się niepowodzeniem (aktualizacja wiersza 2). Wygląda na to, że T1 blokuje odczyt wiersza 4 również, a ponieważ T2 go modyfikuje, T1 kończy się niepowodzeniem z powodu poziomu izolacji transakcji (POWTARZALNY ODCZYT domyślnie ). Ostatecznym rozwiązaniem byłaby gra z Poziomami izolacji transakcji , używając READ UNCOMMITTED lub READ COMMITTED poziomy transakcji.

Najprostsza to Opcja 1 , IMHO, ale to zależy od Twoich możliwości.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak dodać ograniczenie sprawdzające w migracji Railsów?

  2. PL/MySQL czy to istnieje?

  3. wywołanie funkcji mysql zwracającej varchar w stanie hibernacji

  4. Odkrywanie serwera MySQL Binlog — Ripple

  5. Jak przyznać wszystkie uprawnienia w bazie danych w MySQL?