首頁  >  文章  >  資料庫  >  Mysql 行級鎖的使用及死鎖的預防方案

Mysql 行級鎖的使用及死鎖的預防方案

黄舟
黄舟原創
2017-01-18 11:59:291529瀏覽

Mysql關係型資料庫管理系統

MySQL是一個開放式原始碼的小型關聯式資料庫管理系統,開發者為瑞典MySQL AB公司。 MySQL被廣泛地應用在Internet上的中小型網站。由於其體積小、速度快、總體擁有成本低,尤其是開放原始碼這一特點,許多中小型網站為了降低網站總體擁有成本而選擇了MySQL作為網站資料庫。


mysql的InnoDB,支援事務和行級鎖定,可以使用行鎖來處理使用者提現等業務。使用mysql鎖的時候有時候會出現死鎖,要做好死鎖的預防。這篇文章透過實例應用程式跟大家講解

一、前言

    mysql的InnoDB,支援事務和行級鎖,可以使用行鎖來處理使用者提現等業務。使用mysql鎖的時候有時候會出現死鎖,要做好死鎖的預防。

二、MySQL行級鎖定

    行級鎖又分共享鎖定和排他鎖。

    共享鎖:

      名詞解釋:共享鎖又叫做讀鎖,所有的事務只能對其進行讀取操作不能寫操作,加上共享鎖後其他事務不能加排鎖鎖了。

      用法:

SELECT `id` FROM table WHERE id in(1,2)  LOCK IN SHARE MODE

結果集的資料都會加共享鎖

    排他鎖:

     排他這一行不能對其進行加任何鎖,其他進程可以讀取,不能進行寫入操作,需等待其釋放。

      用法:

SELECT `id` FROM mk_user WHERE id=1 FOR UPDATE

三、實例應用

<?php
  $uid=$_SESSION[&#39;uid&#39;];
  //开启事务
  sql:begin
  //开启行级锁的排他锁
  sql:SELECT `coin` FROM user WHERE id=$uid FOR UPDATE 
  //扣除用户账户钱币
  $res=update user set coin=coin-value where id=1;
  if($res){
   //将用户的提现信息添加到提现表
   sql:insert into user values(null,"{$uid}",value);
   //判断添加结果
   if(add_cash_result){
    sql:commit
   }else{
    sql:rollback
   }
  }else{
   sql:rollback;
  }

 其實步驟不復雜,就是開啟事務判斷各個結果為真就提交為假就回滾。單一排他鎖沒有什麼問題,當一個表關聯到多個排他鎖的時候要注意防止發生死鎖。

四、死鎖

    `id`  主鍵索引

    `name` index 索引

    `name` index 索引

 合  是兩個以上的進程都要求對方釋放資源,以至於進程都一直等待。在程式碼上是因為兩個或以上的事務都要求另一個釋放資源。

    死鎖產生的四個必要條件:互斥條件、環路條件、請求保持、不可剝奪,缺一不可,相對應的只要破壞其中一種條件死鎖就不會產生。

    例如下面兩條語句第一條語句會優先使用`name`索引,因為name不是主鍵索引,還會用到主鍵索​​引

    第二條語句是首先使用主鍵索引

    第二條語句是首先使用主鍵索引,兩條再使用name索引語句同時執行,第一個語句執行了name索引等待第二個釋放主鍵索引,第二個執行了主鍵索引等待第一個的name索引,這樣就造成了死鎖。

    解決方法:改造第一條語句使其根據主鍵值進行更新

#①
update mk_user set name =&#39;1&#39; where `name`=&#39;idis12&#39;;
#②
update mk_user set name=&#39;12&#39; where id=12;
//改造后
update mk_user set name=&#39;1&#39; where id=(select id from mk_user where name=&#39;idis12&#39; );

以上就是Mysql 行級鎖的使用及死鎖的預防方案的內容,更多相關內容請關注PHP中文網(www. php.cn)!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn