mysql--讀寫鎖
一.簡介
假設現在有這樣一個場景:假設現在有一個郵箱,在同一時刻無論是單個還是多個使用者併發的去讀取某一封郵件,都沒有問題。因為讀取郵件並不會修改資料,所以不會出錯;
但是某個使用者正在讀取某一封郵件時,同時另一個使用者正在刪除這封郵件,那麼讀取郵件的使用者可能會因為找不到而退出。
解決此類問題的方法就是併發控制,在併發讀或者寫時,可以通過讀鎖(read lock)或寫鎖(write lock)來解決問題,讀鎖和寫鎖也被成為共享鎖(shared lock)和排它鎖(exclusive lock)。
讀鎖:讀鎖是共享的,或者說是互不干涉的。多個客戶端在同一時刻可以同時讀取一個資源,而互不干擾。
寫鎖:寫鎖則是排他的,也就是說一個寫鎖會阻塞其他的寫鎖和讀鎖,只有這樣才能保證在給定的時間裡,只有一個使用者能執行寫入,並防止其他使用者讀取正在寫入的同一資源。
二.演示
讀鎖:
事務一 | 事務二 |
mysql> set autocommit=0; #事務不主動提交 |
mysql> set autocommit=0; |
#查詢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=1的使用者進行修改 mysql> update user set name='ludy' where id=1; 正在等待中... |
|
#此時提交事務 mysql> commit; |
|
#修改成功 mysql> update user set name='ludy' where id=1; |
寫鎖:
事務一 | 事務二 | 事務三 |
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=1的使用者資訊 mysql> select * from user where id=1 for update; 等待中... |
||
#其他事務對id=1進行修改 mysql> update user set name='timi' where id = 1; 等待中... |
||
#提交事務 釋放鎖 mysql> commit; |
||
#查詢成功 | #修改成功 |
for update是有超時時間的,當一個事務等待時間超過設定的超時時間時,將會獲得鎖。
超時時間可通過show global VARIABLES like "%timeout%";命令檢視,innodb_lock_wait_timeout就是。
三.總結
讀寫鎖的本質都是行級鎖,而在Mysql中只有Innodb支援行級鎖。
Innodb將通過檢索條件中的索引來加鎖,如果沒有檢索條件則對所有記錄加鎖,即表鎖。
本文來自部落格園,作者:EchoLv,轉載請註明原文連結:https://www.cnblogs.com/lvdeyinBlog/p/15231416.html