选择锁定共享模式

时间:2011-07-07 07:02:11

标签: mysql locking innodb

我已阅读this article from dev.mysql

该页面中的

是一个例子,当使用select for update并且不要在共享模式下使用lock并说

  

这里,LOCK IN SHARE MODE并不好   解决方案,因为如果两个用户读取   同时反击,至少一个   当它结束时,它们会以死锁结束   试图更新计数器

但是本页的第一行说

  

选择...锁定共享模式:   行读取是最新的, **所以   如果他们属于另一个交易**   还没有提交,阅读   阻止该交易结束

有悖论吗?

我的意思是两个用户在同一时间不读取计数器 如果他们属于另一个交易阅读  阻止该交易结束。

2 个答案:

答案 0 :(得分:20)

如果有另一个已修改行的事务,则SELECT ... LOCK IN SHARE MODE等待。如果未修改该行,则不会等待。这导致了第一种情况,即2个事务可以SELECT ... LOCK IN SHARE MODE,但是没有一个可以更新记录(死锁)

答案 1 :(得分:14)

试试这个。打开两个终端,例Windows中的powershell,xterm,Linux中的控制台,....连接到MySQL:

create table child_codes(取自MySQL documentation

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

我也认为如果其他事务在共享模式下执行查询选择锁定,则会阻止此查询(等待其他事务提交或回滚)。但是像Darhazer提到的那样如果没有修改行,它就不会等待。我相信在MySQL文档中必须提到这种行为。