MYSQL SELECT....FOR UPDATE

MYSQL SELECT...FOR UPDATE 的理解
1溢豆、背景:

現(xiàn)在有這樣的需求,插入數(shù)據(jù)時瘸羡,判斷test表有無username為‘mraz’的數(shù)據(jù)漩仙,無則插入,有則提示“已插入”犹赖,目的就是想只插入一條username為‘mraz’的記錄队他。

2、一般程序邏輯如下:

    $conn = mysqli_connect('127.0.0.1', 'root', '111111') or die(mysqli_error());
     
    mysqli_select_db($conn, 'mraz');
     
    $rs = mysqli_query($conn, 'SELECT count(*) as total FROM test WHERE username = "mraz" ');
    $row = mysqli_fetch_array($rs);
    if($row['total']>0){
        exit('exist');
    }
     
    mysqli_query($conn, "insert into test(username) values ('mraz')");
    var_dump('error:'.mysqli_errno($conn));
    $insert_id = mysqli_insert_id($conn);
     
    echo 'insert_id:'.$insert_id.'<br>';
     
    mysqli_free_result($rs);
    mysqli_close($conn);

3峻村、一般少量請求的時候麸折,程序邏輯不會有問題。但是一旦高并發(fā)請求執(zhí)行的話粘昨,程序并沒有按預(yù)期執(zhí)行垢啼,會插入多條username為‘mraz’的記錄。

4雾棺、解決方案:利用mysql的FOR UPDATE 語句和事務(wù)的隔離性膊夹。注意的是FOR UPDATE僅適用于InnoDB,且必須在事務(wù)(BEGIN/COMMIT)中才能生效捌浩。

調(diào)整代碼后如下:

$conn = mysqli_connect('127.0.0.1', 'root', '111111') or die(mysqli_error());
 
mysqli_select_db($conn, 'mraz');
mysqli_query($conn, 'BEGIN');
$rs = mysqli_query($conn, 'SELECT count(*) as total FROM test WHERE username = "mraz" FOR UPDATE');
$row = mysqli_fetch_array($rs);
if($row['total']>0){
    exit('exist');
}
 
mysqli_query($conn, "insert into test(username) values ('mraz')");
var_dump('error:'.mysqli_errno($conn));
$insert_id = mysqli_insert_id($conn);
 
mysqli_query($conn, 'COMMIT');
echo 'insert_id:'.$insert_id.'<br>';
 
mysqli_free_result($rs);
mysqli_close($conn);

注意

順帶一提的是,
當(dāng)選中某一個行的時候,如果是通過主鍵id選中的放刨。那么這個時候是行級鎖。
主鍵+普通索引/唯一索引/無索引 行級鎖
唯一索引+普通索引/無索引 行級鎖
普通索引+無索引 行級鎖
其他的行還是可以直接insert 或者update的尸饺。如果是通過其他的方式選中行,或者選中的條件不明確包含主鍵进统。這個時候會鎖表。其他的事務(wù)對該表的任意一行記錄都無法進(jìn)行插入或者更新操作浪听。只能讀取螟碎。
如果明確指定主鍵,若查無此數(shù)據(jù)迹栓,則無lock
SELECT * FROM products WHERE id='-1' FOR UPDATE;

附上apache的ab測試并發(fā)的方法

ab -n 100 -c 100  127.0.0.1/test.php
//意思是同時有100人訪問
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末掉分,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌酥郭,老刑警劉巖华坦,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異不从,居然都是意外死亡惜姐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門椿息,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歹袁,“玉大人,你說我怎么就攤上這事寝优√跆颍” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵倡勇,是天一觀的道長逞刷。 經(jīng)常有香客問我,道長妻熊,這世上最難降的妖魔是什么夸浅? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮扔役,結(jié)果婚禮上帆喇,老公的妹妹穿的比我還像新娘。我一直安慰自己亿胸,他們只是感情好坯钦,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著侈玄,像睡著了一般婉刀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上序仙,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天突颊,我揣著相機(jī)與錄音,去河邊找鬼潘悼。 笑死律秃,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的治唤。 我是一名探鬼主播棒动,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼宾添!你這毒婦竟也來了船惨?” 一聲冷哼從身側(cè)響起柜裸,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掷漱,沒想到半個月后粘室,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡卜范,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鹿榜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片海雪。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖舱殿,靈堂內(nèi)的尸體忽然破棺而出奥裸,到底是詐尸還是另有隱情,我是刑警寧澤沪袭,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布湾宙,位于F島的核電站,受9級特大地震影響冈绊,放射性物質(zhì)發(fā)生泄漏侠鳄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一死宣、第九天 我趴在偏房一處隱蔽的房頂上張望伟恶。 院中可真熱鬧,春花似錦毅该、人聲如沸博秫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挡育。三九已至,卻和暖如春朴爬,著一層夾襖步出監(jiān)牢的瞬間即寒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工寝殴, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留蒿叠,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓蚣常,卻偏偏與公主長得像市咽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子抵蚊,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348