官網資料:http://dev.mysql.com/doc/refman/5.7/en/lock-tables.html
[鎖定的指令]
- LOCK TABLES 資料表 READ;
讀取:全部連線(session)都可讀取。
寫入:全部連線都不可寫入,包括自己也不可寫入。
取得條件:無其他連線取得 WRITE LOCK 的時候。 - LOCK TABLES 資料表 READ LOCAL;
讀取:全部連線(session)都可讀取。
寫入:全部連線都不可寫入,包括自己也不可寫入。但可 INSERT 不影響現有資料的 SQL 指令。
取得條件:無其他連線取得 WRITE LOCK 的時候。 - LOCK TABLES 資料表 WRITE;
讀取:自己可讀取,其他使用者不行。
寫入:自己可寫入,其他使用者不行。
取得條件:無其他連線取得 WRITE LOCK、READ LOCK 的時候。 - LOCK TABLES 資料表 LOW_PRIORITY WRITE;
讀取:自己可讀取,其他使用者不行。
寫入:自己可寫入,其他使用者不行。
取得條件:無其他連線取得 WRITE LOCK、READ LOCK 的時候。
LOW_PRIORITY:等待其他鎖定被釋放的期間,允許其他人取得鎖定。MySQL 5.6.5 以後此設定已無效。 - 若鎖定過程,須操作多個資料表時,須鎖定多個資料表,否則會出現 was not locked with LOCK TABLES 錯誤。
同時鎖定兩個資料表:LOCK TABLES aaa WRITE, bbb WRITE - 若鎖定過程,會另外將資料表命名別名,須連同別名也一同鎖定,否則會出現 was not locked with LOCK TABLES 錯誤
同時鎖定資料表別名:LOCK TABLES aaa WRITE, aaa AS a WRITE - 範例
下圖為第1個連線,使用 WRITE 的方式,先 LOCK 住 aa 資料表。自己還是能讀取資料表。
下圖為第2個連線,要讀取 aa 資料表時,因為資料表已被第一個連線 LOCK,所以無法讀取,一直在等待 aa 資料表解除鎖定。
[解鎖的指令]
- UNLOCK TABLES;
範例:LOCK TABLES test READ; -- --其他 SQL 指令 -- UNLOCK TABLES;
[其他相關指令]
- GET_LOCK(鎖定名稱, 等待幾秒)
SELECT GET_LOCK('aa',10); --最多等 10 秒,嘗試取得名稱為"aa"的鎖定 --成功 select 得到1,失敗得到0
http://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_get-lock - RELEASE_LOCK(鎖定名稱)
SELECT RELEASE_LOCK('aa'); --釋放名稱為"aa"的鎖定
http://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_release-lock - 當某"名稱"先被其他連線鎖定時。其他連線要用同樣的名稱執行 GET_LOCK() 時會卡住,超過等待時間時,會返回失敗。
- GET_LOCK 和 RELEASE_LOCK 不實際鎖定資料表,只是提供某名稱是否有人鎖定,所以其他人還是可正常讀寫資料表。
因此,在同時多連線,要避免某些 SQL 指令交錯執行,也可用"鎖定某名稱的方式"來判斷是否有其他連線正在執行這些的 SQL 指令,以確保期執行期間,不會有其他連線進來交互執行這些 SQL 指令。
沒有留言:
張貼留言