ВЫБЕРИТЕ БЛОКИРОВКУ В РЕЖИМЕ ОБМЕНА - PullRequest
19 голосов
/ 07 июля 2011

Я прочитал эту статью с dev.mysql .

на этой странице - пример, который при использовании выбирают для обновления и не использует блокировку в режиме общего доступа, и говорит

Здесь, LOCK IN SHARE MODE не является хорошим решением, потому что, если два пользователя читают счетчик одновременно , по крайней мере один из них оказывается в deadlock , когдаон пытается обновить счетчик

, но в первой строке этой страницы написано

SELECT ... LOCK IN SHARE MODE: прочитанные строки являются самыми последними доступными, ** поэтому, если они принадлежат другой транзакции **, которая еще не зафиксирована, считывает блоки до тех пор, пока эта транзакция не завершится .

, есть ли парадокс?

Я имею в виду, что два пользователя не читают счетчик одновременно, потому что, если они принадлежат другой транзакции, блоки чтения считываются до тех пор, пока эта транзакция не завершится.

Ответы [ 2 ]

20 голосов
/ 07 июля 2011

Если есть другая транзакция, которая изменила строку, то SELECT ... LOCK IN SHARE MODE ждет. Если строка не изменена, она не ждет. Это приводит к первой ситуации, когда 2 транзакция может выбрать SELECT ... LOCK IN SHARE MODE, но ни одна из них не может обновить запись (взаимоблокировка)

14 голосов
/ 12 декабря 2013

Попробуй это.Откройте два терминала, например powershell в Windows, xterm, консоль в Linux, .... Подключитесь к MySQL:

создайте таблицу child_codes (взято из документации MySQL )

mysql> create table child_codes (counter_field integer);
Query OK, 0 rows affected (0.05 sec)

mysql> insert into child_codes set counter_field = 1;
Query OK, 1 row affected (0.00 sec)

session 1 (terminal 1):              session 2 (terminal 2):                                                                        

                                            mysql> start transaction;
                                            Query OK, 0 rows affected (0.00 sec)

                                            mysql> select counter_field from child_codes
                                                      lock in share mode;
                                            +---------------+
                                            | counter_field |
                                            +---------------+
                                            |             1 |
                                            +---------------+
                                            1 row in set (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select counter_field from
          child_codes lock in share mode;
+---------------+
| counter_field |
+---------------+
|             1 |
+---------------+

                                             mysql> update child_codes set counter_field = 2;
                                             ERROR 1205 (HY000): Lock wait timeout exceeded;
                                             try restarting transaction

Я тоже думал, что если другая транзакция выполняет запрос, выберите блокировку в режиме общего доступа, этот запрос блокируется (ожидание другой транзакции для фиксации или отката).Но, как упоминал Дархазер, Если строка не изменена, она не ждет .Я считаю, что это поведение должно быть упомянуто в документации MySQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...