mysql表鎖演示的語句

mysql表鎖演示的語句

 

首先看表結構,引擎innodb 

  www.aiwalls.com  

+—-+———-+——+ 

| id | name     | seat | 

+—-+———-+——+ 

|  1 | 管理員        |   98 | 

|  2 | 維護人員       |   98 | 

|  3 | 主任         |   97 | 

|  4 | 班主任         |   96 | 

+—-+———-+——+ 

 

id是主鍵,沒有其他索引。 

 

先看表鎖的情況 

發sql: 

 

set autocommit=0; 

select * from role where seat=98 for update; 

 

這裡註意,set autocommit=0是必不可少的,因為如果數據很快就提交的話,鎖就會自動釋放。 

  www.aiwalls.com  

再發一條sql查詢:select * from role where id = 1; 

顯示結果: 

+—-+——–+——+ 

| id | name   | seat | 

+—-+——–+——+ 

|  1 | 管理員      |   98 | 

+—-+——–+——+ 

1 row in set (0.00 sec) 

 

這是因為select 操作 無關乎鎖定。 

  www.aiwalls.com  

然後看寫操作:update role set seat=99 where id =3; 

 

可以看到,漫長的等待後(超過mysql默認的執行時間之後),顯示如下結果 

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction 

 

此時我們看鎖定記錄: 

 

發sql:SHOW PROCESSLIST; 

 

+—-+——+—————–+———+———+——+——-+————– 

—-+ 

| Id | User | Host            | db      | Command | Time | State | Info 

    | 

+—-+——+—————–+———+———+——+——-+————– 

—-+ 

|  7 | root | localhost:50903 | mybatis | Sleep   | 1403 | NULL  | NULL 

    | 

| 16 | root | localhost:51326 | mybatis | Query   |    0 | NULL  | SHOW PROCESSL 

IST | 

+—-+——+—————–+———+———+——+——-+————– 

—-+ 

  www.aiwalls.com  

第6列Time 1403 表示鎖定時間,單位秒。 

 

結論:當where條件後面的列不是索引的時候,加上for update 會鎖定全表,以至於後面任何記錄都不能執行讀寫操作。比如本條id=3時,seat=97. 並不是查詢時候的條件98.仍然是給鎖住瞭,update不瞭。 

 

把鎖kill掉,寫操作就可以繼續瞭: 

發sql: kill 7; 

這裡就不演示效果瞭。 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *