成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

MySQL 樂觀鎖于悲觀鎖

liuyix / 3291人閱讀

摘要:樂觀鎖樂觀鎖實(shí)際上是一種邏輯思想,并不是數(shù)據(jù)庫的特性。悲觀鎖利用了存儲引擎的支持行鎖的特性。建議在用戶并發(fā)量不大的應(yīng)用場景下,采用樂觀鎖的方式。在對數(shù)據(jù)一致性要求很高的情況下,可以犧牲一下性能,采用悲觀鎖。

MySQL5.5 版本之后默認(rèn)采用innoDb 數(shù)據(jù)引擎.本文采用默認(rèn)的存儲引擎。
樂觀鎖
樂觀鎖實(shí)際上是一種邏輯思想,并不是mysql 數(shù)據(jù)庫的特性。這個(gè)要區(qū)分清楚。
實(shí)現(xiàn)數(shù)據(jù)版本有兩種方式,第一種是使用版本號,第二種是使用時(shí)間戳。

使用方式:

/** 偽代碼  number 庫存  goods_id 商品ID  version 版本號默認(rèn)為0 **/

$sql="select number from goods where goods_id={$goods_id} and version= {$version} ";

// 時(shí)間戳方式查詢庫存
$sql="select number from goods where goods_id={$goods_id} and time < time() ";

$rs=mysqli_query($conn,$sql);

$row = $rs->fetch_assoc();

if($row["number"]>0){//高并發(fā)下會導(dǎo)致超賣

    if($row["number"]<$number){

        return insertLog("庫存不夠",3,$username);
    }

//庫存減少
 $sql="update goods set number=number-{$number},version += 1 where goods_id={$goods_id}  and number>0";

// 時(shí)間戳方式減少庫存
$sql="update goods set number=number-{$number},time = time() where goods_id={$goods_id}  and number>0";

$store_rs=mysqli_query($conn,$sql);

if($store_rs){

//生成訂單,返回操作成功
                    
echo json_encode(array("code"=>0,"msg"=>"庫存減少成功","data"=>$username));

}else{
   echo json_encode(array("code"=>1,"msg"=>"庫存減少失敗","data"=>$username));
}
}else{
    echo json_encode(array("code"=>3,"msg"=>"庫存減少失敗","data"=>$username));
}
      
            
注意:使用樂觀鎖需要注意啊,將庫存字段number字段設(shè)為unsigned,當(dāng)庫存為0時(shí),因?yàn)樽侄尾荒転樨?fù)數(shù),將會返回false
悲觀鎖
悲觀鎖指的是對數(shù)據(jù)被外界(包括本系統(tǒng)當(dāng)前的其他事務(wù),以及來自外部系統(tǒng)的事務(wù)處理)修改持保守態(tài)度,因此,在整個(gè)數(shù)據(jù)處理過程中,將數(shù)據(jù)處于鎖定狀態(tài)。悲觀鎖的實(shí)現(xiàn),往往依靠數(shù)據(jù)庫提供的鎖機(jī)制(也只有數(shù)據(jù)庫層提供的鎖機(jī)制才能真正保證數(shù)據(jù)訪問的排他性,否則,即使在本系統(tǒng)中實(shí)現(xiàn)了加鎖機(jī)制,也無法保證外部系統(tǒng)不會修改數(shù)據(jù))。

悲觀鎖利用了MySQL innoDB 存儲引擎的支持行鎖的特性。一行一行操作數(shù)據(jù).

使用方式:

// 使用悲觀鎖鎖住當(dāng)前行
$sql="select number from goods where goods_id={$goods_id} for update ";

// 減少庫存操作
$sql="update goods set number=number-{$number} where goods_id={$goods_id}  and number>0";
   
注意:innoDB 行鎖是基于索引來執(zhí)行的,where 條件后必須有索引,不然走的就是全表掃描。

優(yōu)點(diǎn)與不足

悲觀并發(fā)控制實(shí)際上是“先取鎖再訪問”的保守策略,為數(shù)據(jù)處理的安全提供了保證。但是在效率方面,處理加鎖的機(jī)制會讓數(shù)據(jù)庫產(chǎn)生額外的開銷,還有增加產(chǎn)生死鎖的機(jī)會;另外,在只讀型事務(wù)處理中由于不會產(chǎn)生沖突,也沒必要使用鎖,這樣做只能增加系統(tǒng)負(fù)載;還有會降低了并行性,一個(gè)事務(wù)如果鎖定了某行數(shù)據(jù),其他事務(wù)就必須等待該事務(wù)處理完才可以處理那行數(shù)

樂觀并發(fā)控制相信事務(wù)之間的數(shù)據(jù)競爭(datarace)的概率是比較小的,因此盡可能直接做下去,直到提交的時(shí)候才去鎖定,所以不會產(chǎn)生任何鎖和死鎖。但如果直接簡單這么做,還是有可能會遇到不可預(yù)期的結(jié)果,例如兩個(gè)事務(wù)都讀取了數(shù)據(jù)庫的某一行,經(jīng)過修改以后寫回?cái)?shù)據(jù)庫,這時(shí)就遇到了問題。

建議: 在用戶并發(fā)量不大的應(yīng)用場景下,采用樂觀鎖的方式。在對數(shù)據(jù)一致性要求很高的情況下,可以犧牲一下性能,采用悲觀鎖。這個(gè)兩種方式的前提是采用MySQL的解決方案。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/31279.html

相關(guān)文章

  • 并發(fā)同步控制

    摘要:并發(fā)同步控制遇到并發(fā)時(shí),我們避免不了要談并發(fā)控制。它會阻塞其它的線程執(zhí)行,如果當(dāng)前線程一直持有的監(jiān)控鎖,就會把其它線程一直阻塞下去。如果此時(shí)線程和線程同時(shí)進(jìn)入方法,用一段語言描述方法的執(zhí)行過程,可能是這樣子。 并發(fā)同步控制 遇到并發(fā)時(shí),我們避免不了要談并發(fā)控制。在Java語言中,我們談并發(fā)時(shí),要談到Object的監(jiān)控鎖。在MySQL的數(shù)據(jù)庫并發(fā)中,我們也要談到mysql的鎖機(jī)制。 這樣...

    graf 評論0 收藏0

發(fā)表評論

0條評論

liuyix

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<