一、前言
mysql的InnoDB,支持事務(wù)和行級鎖,可以使用行鎖來處理用戶提現(xiàn)等業(yè)務(wù)。使用mysql鎖的時候有時候會出現(xiàn)死鎖,要做好死鎖的預(yù)防。
二、MySQL行級鎖
行級鎖又分共享鎖和排他鎖。
共享鎖:
名詞解釋:共享鎖又叫做讀鎖,所有的事務(wù)只能對其進行讀操作不能寫操作,加上共享鎖后其他事務(wù)不能再加排他鎖了只能加行級鎖。
用法:
SELECT `id` FROM table WHERE id in(1,2) LOCK IN SHARE MODE
結(jié)果集的數(shù)據(jù)都會加共享鎖
排他鎖:
名詞解釋:若某個事物對某一行加上了排他鎖,只能這個事務(wù)對其進行讀寫,其他事務(wù)不能對其進行加任何鎖,其他進程可以讀取,不能進行寫操作,需等待其釋放。
用法:
SELECT `id` FROM mk_user WHERE id=1 FOR UPDATE
三、實例應(yīng)用
?php $uid=$_SESSION['uid']; //開啟事務(wù) sql:begin //開啟行級鎖的排他鎖 sql:SELECT `coin` FROM user WHERE id=$uid FOR UPDATE //扣除用戶賬戶錢幣 $res=update user set coin=coin-value where id=1; if($res){ //將用戶的提現(xiàn)信息添加到提現(xiàn)表 sql:insert into user values(null,"{$uid}",value); //判斷添加結(jié)果 if(add_cash_result){ sql:commit }else{ sql:rollback } }else{ sql:rollback; }
其實步驟不復(fù)雜,就是開啟事務(wù)判斷各個結(jié)果為真就提交為假就回滾。單個排他鎖沒有什么問題,當(dāng)一個表關(guān)聯(lián)到多個排他鎖的時候要注意防止發(fā)生死鎖。
四、死鎖
`id` 主鍵索引
`name` index 索引
`age` 普通字段
死鎖產(chǎn)生的根本原因是兩個以上的進程都要求對方釋放資源,以至于進程都一直等待。在代碼上是因為兩個或者以上的事務(wù)都要求另一個釋放資源。
死鎖產(chǎn)生的四個必要條件:互斥條件、環(huán)路條件、請求保持、不可剝奪,缺一不可,相對應(yīng)的只要破壞其中一種條件死鎖就不會產(chǎn)生。
例如下面兩條語句 第一條語句會優(yōu)先使用`name`索引,因為name不是主鍵索引,還會用到主鍵索引
第二條語句是首先使用主鍵索引,再使用name索引 如果兩條語句同時執(zhí)行,第一條語句執(zhí)行了name索引等待第二條釋放主鍵索引,第二條執(zhí)行了主鍵索引等待第一條的name索引,這樣就造成了死鎖。
解決方法:改造第一條語句 使其根據(jù)主鍵值進行更新
#① update mk_user set name ='1' where `name`='idis12'; #② update mk_user set name='12' where id=12; //改造后 update mk_user set name='1' where id=(select id from mk_user where name='idis12' );
以上所述是小編給大家介紹的Mysql 行級鎖的使用及死鎖的預(yù)防解決方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
標(biāo)簽:貴州 重慶 天津 內(nèi)蒙古 湖州 成都 常德 臨沂
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Mysql 行級鎖的使用及死鎖的預(yù)防方案》,本文關(guān)鍵詞 Mysql,行級,鎖,的,使用,及,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。