1. 程式人生 > 其它 >mysql--讀寫鎖

mysql--讀寫鎖

一.簡介

假設現在有這樣一個場景:假設現在有一個郵箱,在同一時刻無論是單個還是多個使用者併發的去讀取某一封郵件,都沒有問題。因為讀取郵件並不會修改資料,所以不會出錯;

但是某個使用者正在讀取某一封郵件時,同時另一個使用者正在刪除這封郵件,那麼讀取郵件的使用者可能會因為找不到而退出。

解決此類問題的方法就是併發控制,在併發讀或者寫時,可以通過讀鎖(read lock)寫鎖(write lock)來解決問題,讀鎖和寫鎖也被成為共享鎖(shared lock)排它鎖(exclusive lock)。

讀鎖:讀鎖是共享的,或者說是互不干涉的。多個客戶端在同一時刻可以同時讀取一個資源,而互不干擾。

寫鎖:寫鎖則是排他的,也就是說一個寫鎖會阻塞其他的寫鎖和讀鎖,只有這樣才能保證在給定的時間裡,只有一個使用者能執行寫入,並防止其他使用者讀取正在寫入的同一資源。

二.演示

讀鎖:

事務一 事務二

mysql> set autocommit=0; #事務不主動提交
Query OK, 0 rows affected (0.00 sec)

mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

#查詢id為1的使用者資訊並加上共享鎖

mysql> select * from user where id = 1 lock in share mode;


+----+----------+------+------+--------------------+
| id | password | name | age | email |
+----+----------+------+------+--------------------+
| 1 | NULL | lv | 18 | [email protected] |
+----+----------+------+------+--------------------+
1 row in set (0.00 sec)

#其他事務也能查詢id=1的使用者

mysql> select * from user;
+----+----------+--------+------+--------------------+
| id | password | name | age | email |
+----+----------+--------+------+--------------------+
| 1 | NULL | lv | 18 | [email protected] |
| 2 | NULL | Jack | 20 | [email protected] |
| 3 | NULL | Tom | 28 | [email protected] |
| 4 | NULL | Sandy | 21 | [email protected] |
| 5 | NULL | Billie | 24 | [email protected] |
+----+----------+--------+------+--------------------+
5 rows in set (0.00 sec)

#對id=1的使用者進行修改

mysql> update user set name='ludy' where id=1;

正在等待中...

#此時提交事務

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

#修改成功

mysql> update user set name='ludy' where id=1;
Query OK, 1 row affected (46.30 sec)
Rows matched: 1 Changed: 1 Warnings: 0



寫鎖:

事務一 事務二 事務三
mysql> set autocommit=0;#事務不主動提交
Query OK, 0 rows affected (0.00 sec)
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)
mysql> set autocommit=0;
Query OK, 0 rows affected (0.00 sec)

#將id=1的使用者加入排它鎖

mysql> select * from user where id=1 for update;
+----+----------+------+------+--------------------+
| id | password | name | age | email |
+----+----------+------+------+--------------------+
| 1 | NULL | ludy | 18 | [email protected] |
+----+----------+------+------+--------------------+
1 row in set (0.00 sec)

#此時其他事務訪問id=1的使用者資訊

mysql> select * from user where id=1 for update;

等待中...

#其他事務對id=1進行修改

mysql> update user set name='timi' where id = 1;

等待中...

#提交事務 釋放鎖

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

#查詢成功 #修改成功

for update是有超時時間的,當一個事務等待時間超過設定的超時時間時,將會獲得鎖。

超時時間可通過show global VARIABLES like "%timeout%";命令檢視,innodb_lock_wait_timeout就是。

三.總結

讀寫鎖的本質都是行級鎖,而在Mysql中只有Innodb支援行級鎖。

Innodb將通過檢索條件中的索引來加鎖,如果沒有檢索條件則對所有記錄加鎖,即表鎖。

本文來自部落格園,作者:EchoLv,轉載請註明原文連結:https://www.cnblogs.com/lvdeyinBlog/p/15231416.html