怎樣理解mysql innodb的行級鎖?

來源:互聯網
上載者:User
關鍵字 mysql php thinkphp
因為最近在做公司的一個秒殺項目,就是現在一些購物網站最常見的那種。但是考慮到並發的一些問題(也許並發不是主要的,主要的是現在有秒殺就會出現秒殺工具之類的)導致被秒出去的商品比實際庫存還要多,所以就上網看了一下mysql的鎖,公司用的是innodb引擎,thinkphp3.2架構,根據網上的相關資料,應該用的是行級鎖(對於mysql,本人菜鳥,懂的不是很深入)。

 public function test_sql(){        set_time_limit(0);        $model = D('Liren/GroupPurchase');        $row = $model->lock(true)->where(array('id'=>1))->find();        if($row){            dump($row);            sleep(10);        }    }

test_sql 方法是帶鎖查詢了一條資料,之後延時了十秒,在這同時,我開了另一個進程:

 public function test_lock(){        $model = D('Liren/GroupPurchase');        $info = $model->find(1);        if($info){            dump($info);        }            }

在test_sql沒有結束之前test_lock一直在等待。而且就算我在test_lock方法中查詢的不是主鍵(id)為1的資料,也同樣要等到test_sql結束之後才能執行。這樣的話是不是整個表都鎖住了,是不是需要繼承thinkphp的AdvModel才能真正實現行級鎖?

還有一個問題。事務和鎖之間存在關係嗎?

public function test_sql(){        set_time_limit(0);        $model = D('Liren/GroupPurchase');        $model->startTrans();        $row = $model->lock(true)->where(array('id'=>1))->find();       // echo $model->getLastSql();        if($row){            $ret = $model->lock(true)->save(array('id'=>1,'is_show'=>0));            echo $model->getLastSql();        }        if($ret){            $model->commit();            sleep(10);            echo 'success';        }    }    

雖然事務是提交了,資料庫的狀態也一早就改變了,但還是必須等到test_sql進程結束之後 test_lock 方法才能輸出資料,如果能在事務結束的時候表鎖就能結束,這樣是不是好一點。

小弟愚鈍,望指點!

回複內容:

因為最近在做公司的一個秒殺項目,就是現在一些購物網站最常見的那種。但是考慮到並發的一些問題(也許並發不是主要的,主要的是現在有秒殺就會出現秒殺工具之類的)導致被秒出去的商品比實際庫存還要多,所以就上網看了一下mysql的鎖,公司用的是innodb引擎,thinkphp3.2架構,根據網上的相關資料,應該用的是行級鎖(對於mysql,本人菜鳥,懂的不是很深入)。

 public function test_sql(){        set_time_limit(0);        $model = D('Liren/GroupPurchase');        $row = $model->lock(true)->where(array('id'=>1))->find();        if($row){            dump($row);            sleep(10);        }    }

test_sql 方法是帶鎖查詢了一條資料,之後延時了十秒,在這同時,我開了另一個進程:

 public function test_lock(){        $model = D('Liren/GroupPurchase');        $info = $model->find(1);        if($info){            dump($info);        }            }

在test_sql沒有結束之前test_lock一直在等待。而且就算我在test_lock方法中查詢的不是主鍵(id)為1的資料,也同樣要等到test_sql結束之後才能執行。這樣的話是不是整個表都鎖住了,是不是需要繼承thinkphp的AdvModel才能真正實現行級鎖?

還有一個問題。事務和鎖之間存在關係嗎?

public function test_sql(){        set_time_limit(0);        $model = D('Liren/GroupPurchase');        $model->startTrans();        $row = $model->lock(true)->where(array('id'=>1))->find();       // echo $model->getLastSql();        if($row){            $ret = $model->lock(true)->save(array('id'=>1,'is_show'=>0));            echo $model->getLastSql();        }        if($ret){            $model->commit();            sleep(10);            echo 'success';        }    }    

雖然事務是提交了,資料庫的狀態也一早就改變了,但還是必須等到test_sql進程結束之後 test_lock 方法才能輸出資料,如果能在事務結束的時候表鎖就能結束,這樣是不是好一點。

小弟愚鈍,望指點!

既然是秒殺功能為什麼還要用MySQL呢?為什麼不考慮redis等記憶體快取資料庫呢?
畢竟記憶體的IO效率和磁碟的IO效率之間大概相差了中美之間經濟實力那麼多吧

那麼談談鎖的問題:
相比題主現在對概念應該還有些模糊,我先明確概念:
讀鎖->共用鎖定 (S)
寫鎖 -> 排它鎖 (X)

相容性:

    X           SX    不相容    不相容S    不相容    相容

還有一種叫樂觀鎖/悲觀鎖

這份回答很好,我直接拿來了,總結來說就是:

  • △樂觀鎖是通過邏輯實現,本質上並沒有給資料庫加鎖

  • 悲觀鎖是通過真實的資料庫鎖機制來完成的。

最後回到你的問題:

  • test_sql()函數: 首先要確認,在對錶擷取行鎖的時候,要盡量的使用索引檢索紀錄,如果沒有使用索引訪問,那麼即便你只是要更新其中的一行紀錄,也是全表鎖定的。要確保sql是使用索引來訪問紀錄的,必要的時候,請使用explain檢查sql的執行計畫,判斷是否按照預期使用了索引。
    由於mysql的行鎖是針對索引加的鎖,不是針對紀錄加的鎖,所以雖然是訪問不同行的紀錄,但是如果是相同的索引鍵,是會被加鎖的。

  • 事務和鎖沒什麼關係,鎖的機制與儲存引擎才有關

1.innodb 引擎支援行鎖,但是不指定唯一索引鍵就會鎖表
test_sql 中,使用了悲觀鎖,也就是 select where for update
當 where 條件指定了唯一索引鍵時---行鎖
當非唯一索引鍵時---表鎖

2.在事務中
select 操作共用鎖定
update,delete,insert 排它鎖
commit 會把鎖給取消

InnoDB引擎下,執行的SQL使用行級鎖,還是全表鎖。跟mysql採用的隔離等級、sql會使用到的索引、mysql自身針對這個sql的執行最佳化都有關係。
所以怎麼理解mysql的鎖,需要根據你在用的mysql的具體配置有關。有一篇部落格講的特別透徹,希望對你有用。http://blog.sae.sina.com.cn/archives/2127

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.