天天看點

MySQL鎖的用法之表級鎖

  表級鎖定分為兩類,讀鎖與寫鎖。讀鎖是預期将對資料表進行讀取操作,鎖定期間保證表不能被修改。寫鎖是預期會對資料表更新操作,鎖定期間保證表不能被其他線程更新或讀取。

  讀鎖:

  用法:lock table table_name [ as alias_name ] read

  指定資料表,lock類型為read即可,as别名是可選參數,如果指定别名,使用時也要指定别名才可

  申請讀鎖前提:目前沒有線程對該資料表使用寫鎖,否則申請會阻塞。

  操作限制:其他線程可以對鎖定表使用讀鎖;其他線程不可以對鎖定表使用寫鎖

寫操作

讀操作

使用讀鎖線程

否(報錯)

不使用讀鎖線程

否(阻塞)

   對于使用讀鎖的mysql線程,由于讀鎖不允許任何線程對鎖定表進行修改,在釋放鎖資源前,該線程對表操作隻能進行讀操作,寫操作時會提示非法操作。而 對于其他沒使用鎖的mysql線程,對鎖定表進行讀操作可以正常進行,但是進行寫操作時,線程會等待讀鎖的釋放,當鎖定表的所有讀鎖都釋放時,線程才會響 應寫操作。

  寫鎖:

  用法:lock table table_name [as alias_name] [ low_priority ] write

  别名用法與讀鎖一樣,寫鎖增加了指定優先級的功能,加入low_priority可以指定寫鎖為低優先級。

  申請寫鎖前提:當沒有線程對該資料表使用寫鎖與讀鎖,否則申請回阻塞。

  操作限制:其他mysql線程不可以對鎖表使用寫鎖、讀鎖

使用寫鎖線程

不使用寫鎖線程

能(阻塞)

  對于使用寫鎖的mysql線程,其可以對鎖定表進行讀寫操作。但是對于其他線程,對指定表讀寫操作都是非法的,需要等待直到寫鎖釋放。

  鎖配置設定優先級:

  對于鎖配置設定的優先級,是: low_priority write < read < write

  1、當多個線程申請鎖,會優先配置設定給write鎖,不存在write鎖時,才配置設定read鎖,low_priority write需要等到write鎖與read都釋放後,才有機會配置設定到資源。

  2、對于相同優先級的鎖申請,配置設定原則為誰先申請,誰先配置設定。

  注意事項:

  1、不能操作(查詢或更新)沒有被鎖定的表。

query ok, 0 rows affected (0.00 sec)

mysql> select * from test_myisam;

error 1100 (hy000): table 'test_myisam' was not locked with lock tables

  2、不能在一個sql中使用兩次表(除非使用别名)

  當sql語句中多次使用一張表時,系統會報錯。例如:

mysql> lock table test read;

mysql> select * from test where id in (select id from test );

error 1100 (hy000): table 'test' was not locked with lock tables

  解決這個問題的方法是使用别名,如果多次使用到一個表,需要聲明多個别名。

mysql> lock table test as t1 read, test as t2 read;

mysql>  select * from test as t1 where id in (select id from test as t2);

+----+-----------+

| id | content   |

|  1 | tt_1      |

|  3 | new_3     |

|  4 | new_4     |

|  5 | content_5 |

4 rows in set (0.00 sec)

  3、申請鎖時使用别名,使用鎖定表時必須加上别名。

====================================分割線================================

最新内容請見作者的github頁:http://qaseven.github.io/