qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請?jiān)L問 http://qaseven.github.io/

          MySQL鎖的用法之表級鎖

           鎖機(jī)制是數(shù)據(jù)庫有別于文件系統(tǒng)的一個重要的特點(diǎn),也是用來管理并發(fā)訪問的一個有效的方式。MySQL的鎖分為表級鎖、頁級鎖與行級鎖。表級鎖是MySQL中粒度最大的一種鎖,它實(shí)現(xiàn)簡單,資源消耗較少,被大部分MySQL引擎支持。最常使用的MYISAM與INNODB都支持表級鎖定。

            表級鎖定分為兩類,讀鎖與寫鎖。讀鎖是預(yù)期將對數(shù)據(jù)表進(jìn)行讀取操作,鎖定期間保證表不能被修改。寫鎖是預(yù)期會對數(shù)據(jù)表更新操作,鎖定期間保證表不能被其他線程更新或讀取。

            讀鎖:

            用法:LOCK TABLE table_name [ AS alias_name ] READ

            指定數(shù)據(jù)表,LOCK類型為READ即可,AS別名是可選參數(shù),如果指定別名,使用時(shí)也要指定別名才可

            申請讀鎖前提:當(dāng)前沒有線程對該數(shù)據(jù)表使用寫鎖,否則申請會阻塞。

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


          寫操作讀操作
          使用讀鎖線程否(報(bào)錯)
          不使用讀鎖線程否(阻塞)

             對于使用讀鎖的MySQL線程,由于讀鎖不允許任何線程對鎖定表進(jìn)行修改,在釋放鎖資源前,該線程對表操作只能進(jìn)行讀操作,寫操作時(shí)會提示非法操作。而 對于其他沒使用鎖的MySQL線程,對鎖定表進(jìn)行讀操作可以正常進(jìn)行,但是進(jìn)行寫操作時(shí),線程會等待讀鎖的釋放,當(dāng)鎖定表的所有讀鎖都釋放時(shí),線程才會響 應(yīng)寫操作。

            寫鎖:

            用法:LOCK TABLE table_name [AS alias_name] [ LOW_PRIORITY ] WRITE

            別名用法與讀鎖一樣,寫鎖增加了指定優(yōu)先級的功能,加入LOW_PRIORITY可以指定寫鎖為低優(yōu)先級。

            申請寫鎖前提:當(dāng)沒有線程對該數(shù)據(jù)表使用寫鎖與讀鎖,否則申請回阻塞。

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


          寫操作讀操作
          使用寫鎖線程
          不使用寫鎖線程否(阻塞)能(阻塞)

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

            鎖分配優(yōu)先級:

            對于鎖分配的優(yōu)先級,是: LOW_PRIORITY WRITE < READ < WRITE

            1、當(dāng)多個線程申請鎖,會優(yōu)先分配給WRITE鎖,不存在WRITE鎖時(shí),才分配READ鎖,LOW_PRIORITY WRITE需要等到WRITE鎖與READ都釋放后,才有機(jī)會分配到資源。

            2、對于相同優(yōu)先級的鎖申請,分配原則為誰先申請,誰先分配。

            注意事項(xiàng):

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

            例如當(dāng)只申請table1的讀鎖,SQL語句中包含對table2的操作是非法的。例如:

          mysql> LOCK TABLE test READ;
          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中使用兩次表(除非使用別名)

            當(dāng)SQL語句中多次使用一張表時(shí),系統(tǒng)會報(bào)錯。例如:

          mysql> LOCK TABLE test READ;
          Query OK, 0 rows affected (0.00 sec)

          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;
          Query OK, 0 rows affected (0.00 sec)

          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、申請鎖時(shí)使用別名,使用鎖定表時(shí)必須加上別名。

          posted on 2012-09-03 11:15 順其自然EVO 閱讀(2377) 評論(0)  編輯  收藏 所屬分類: 數(shù)據(jù)庫

          <2012年9月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          30123456

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 栾川县| 淮滨县| 和硕县| 牙克石市| 邹城市| 惠安县| 拉萨市| 台安县| 英山县| 连云港市| 漳平市| 安多县| 潞西市| 化隆| 右玉县| 徐州市| 庆云县| 阳春市| 漳浦县| 封丘县| 绥中县| 教育| 蒙自县| 阳春市| 济宁市| 古交市| 灵台县| 宜春市| 连山| 安庆市| 西青区| 高邮市| 中宁县| 长海县| 株洲市| 惠州市| 清涧县| 海林市| 泗水县| 建阳市| 宁远县|