Mysql
 sql >> база данни >  >> RDS >> Mysql

Заключване на ниво ред в Mysql

Вместо FOR UPDATE използвайте LOCK IN SHARE MODE . FOR UPDATE предотвратява и други транзакции да четат реда. LOCK IN SHARE MODE позволява четене, но предотвратява актуализирането.

Справка:Ръководство за MySQL

------ сесия 1

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

----- сесия 2 (която вече не се блокира :) )

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

Актуализация:

Осъзнавайки, четаблицата няма индекс на t , имам следното обяснение:

Първо, транзакция T1 заключва ред 1 в SELECT * FROM test WHERE t=1 FOR UPDATE

След това транзакция T2 се опитва да изпълни UPDATE test SET NAME='irfandd' WHERE t=4 . За да разбере кои редове са засегнати, той трябва да сканира всички редове, включително ред 1 . Но това е заключено, така че T2 трябва да изчака, докато T1 завърши. Ако има някакъв вид индекс, WHERE t=4 може да използва индекса, за да реши дали ред 1 съдържа t=4 или не, така че няма нужда да чакате.

Вариант 1: добавете индекс към test.t така че вашата актуализация може да го използва.

Вариант 2: използвайте LOCK IN SHARE MODE , който е предназначен само за поставяне на заключване за четене. За съжаление тази опция създава блокиране. Интересното е, че транзакцията T2 се изпълнява (актуализиране на ред 4), а T1 се проваля (актуализиране на ред 2). Изглежда, че T1 заключва ред 4 също и тъй като T2 го модифицира, T1 се проваля поради нивото на изолация на транзакциите (ПОВТОРЯЩО ЧЕТЕНЕ по подразбиране ). Окончателното решение би било да се играе с Нива на изолация на транзакциите , с помощта на READ UNCOMMITTED или READ COMMITTED нива на транзакции.

Най-простият еВариант 1 , IMHO, но зависи от вашите възможности.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Изтрийте дублирани mysql редове без първичен ключ

  2. Как да завъртите схема на MySQL обект-атрибут-стойност

  3. проблем с предупреждението:очаква параметър 1 да бъде mysqli_result

  4. Как да разбера дали mysql таблица използва myISAM или InnoDB Engine?

  5. Не са разрешени операции след затваряне на извлечението