真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

MySQL中使用ifnotexists需要注意什么

小編給大家分享一下MySQL中使用if not exists需要注意什么,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

創(chuàng)新互聯(lián)是專(zhuān)業(yè)的浙江網(wǎng)站建設(shè)公司,浙江接單;提供網(wǎng)站設(shè)計(jì)制作、成都做網(wǎng)站,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專(zhuān)業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行浙江網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專(zhuān)業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專(zhuān)業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!



環(huán)境MySQL 5.6.14
事務(wù)隔離級(jí)別 讀提交
事務(wù)的開(kāi)啟和結(jié)束由JAVA程序控制.

上次報(bào)死鎖的過(guò)程,抽象如下

  1. delimitr $$

  2. CREATE PROCEDURE `test_proc`(

  3.     pid int

  4. )

  5. begin

  6.     if not exists (select * from t where id=pid) then

  7.         insert into t(id) values(pid);

  8.     end if;

  9.     

  10.     update t set total=total+1 where id=pid;

  11. end $$

  12. delimiter ; 


死鎖原因已經(jīng)明白了,就是并發(fā)情況下,Insert遇到排它鎖,則嘗試加共享鎖。
在最后Update的時(shí)候,兩個(gè)持有共享鎖的連接,都嘗試申請(qǐng)排它鎖,則導(dǎo)致了死鎖.

但是問(wèn)題是...怎么會(huì)走到了最后一行的Update語(yǔ)句?
另外兩個(gè)連接,不是應(yīng)該在Insert語(yǔ)句時(shí)報(bào) Duplicate entry 'xx' for key 'PRIMARY'錯(cuò)誤嗎?

問(wèn)題應(yīng)該出在這種結(jié)構(gòu)里
if not exists (select * from t where id=pid) then
    xxx
end if;

使用 if not exists 模式,真心要注意啊.在這種結(jié)構(gòu)里出現(xiàn)的異常,不會(huì)報(bào)錯(cuò),而是直接跳出IF判斷,繼續(xù)執(zhí)行!!

實(shí)驗(yàn)準(zhǔn)備

  1. CREATE TABLE `t` (

  2.   `id` int(11) NOT NULL,

  3.   `total` int(11) NOT NULL DEFAULT '0',

  4.   PRIMARY KEY (`id`)

  5. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

  6. truncate table t;

  7. drop procedure if exists test_proc;

  8. delimiter $$

  9. CREATE PROCEDURE `test_proc`(

  10.     pid int,

  11.     ptotal int

  12. )

  13. begin

  14.     if not exists (select * from t where id=pid) then

  15.         insert into t(id,total) value(pid,ptotal);

  16.         update t set total=ptotal+1 where id=pid;

  17.     end if;

  18.     select ptotal+1;    

  19. end $$

  20. delimiter ;


打開(kāi)三個(gè)客戶(hù)端,分別執(zhí)行過(guò)程
MySQL中使用if not exists需要注意什么

第一個(gè)客戶(hù)端執(zhí)行,并沒(méi)有提交.
第二,第三客戶(hù)端處于阻塞狀態(tài).
等第一個(gè)客戶(hù)端提交,

第二個(gè)客戶(hù)端返回 201
第三個(gè)客戶(hù)端返回 301
且沒(méi)有任何的報(bào)錯(cuò)信息.


三個(gè)客戶(hù)端都提交之后,查看T表信息
只有一個(gè)記錄,id為1,total為101

也就是說(shuō),第二個(gè),第三個(gè)客戶(hù)端,在得到主鍵沖突的異常后,沒(méi)有報(bào)錯(cuò),沒(méi)有繼續(xù)執(zhí)行IF塊內(nèi)剩下的語(yǔ)句,而是直接跳出了IF塊,繼續(xù)執(zhí)行IF塊外的語(yǔ)句!!

該報(bào)錯(cuò)的地方不報(bào)錯(cuò),在大段的存儲(chǔ)過(guò)程中,導(dǎo)致死鎖還是小問(wèn)題,就怕引起數(shù)據(jù)的錯(cuò)亂,而不自知.

針對(duì)這種情況,如果有主鍵或者唯一約束,我覺(jué)得干脆改為如下的方式.
delimiter $$
CREATE PROCEDURE `test_proc`(
    pid int,
    ptotal int
)
begin
    insert into t(id,total) value(pid,ptotal);
    update t set total=ptotal+1 where id=pid;
    select ptotal+1;
end $$
delimiter ;

看完了這篇文章,相信你對(duì)“MySQL中使用if not exists需要注意什么”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!


網(wǎng)站標(biāo)題:MySQL中使用ifnotexists需要注意什么
分享網(wǎng)址:http://weahome.cn/article/ipihec.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部