記一次生產(chǎn)環(huán)境mysql死鎖

mysql-binlog

這是Mysql的binlog日志,其中,third_logistics_no、order_no都應(yīng)該是字符串類型,但是這里執(zhí)行的時候變成了數(shù)值型;

業(yè)務(wù)邏輯是:程序在進來的時候首先會鎖住該訂單號的物流記錄,然后執(zhí)行更新語句;

然而在執(zhí)行更新語句的時候,本來應(yīng)該是字符串類型的參數(shù)卻變成了數(shù)值型,給表列賦值與表類型不符合時,MySql底層的優(yōu)化器發(fā)揮作用,會做一個強制類型轉(zhuǎn)化,此時能正常操作,但會導(dǎo)致行鎖升級為表鎖;

重現(xiàn)場景如下:

session1:begin;

session2:begin;

session1:select * from orders where order_no = '001' for update;

session2:select * from orders where order_no = '002' for update;

session1:update orders set order_status = 1 where order_no = 001;// session2上面已經(jīng)獲取了002的鎖,產(chǎn)生了鎖等待,因為MySQL強制類型轉(zhuǎn)換,行鎖變成了表鎖;

session2:update orders set order_status = 2 where order_no = 002;// 執(zhí)行就報了死鎖;

總結(jié):session1等session2的鎖,session2等session1的鎖,同時你等我的鎖,我等你的鎖,然后就死鎖了;
session1

session2

導(dǎo)致這個結(jié)果的原因是因為,sql語句的拼接中使用的是字符串拼接,寫法為:s""" update orders set order_no = ${request} """ 這個寫法
總結(jié)此次教訓(xùn),做了兩個實驗,如下:


image.png

可以看出,雖然我們定義的參數(shù)都是字符串類型,但是由于我們本身的寫法就是scala的字符串拼接,位于scala-lang包下的StringContext,在字符串處理的過程中,這個空串和引號直接被去掉了,得出的sql語句語法上就是錯誤的


image.png

正確的寫法應(yīng)該是用scala-sql,同樣的參數(shù),也是字符串類型,語句和參數(shù)應(yīng)該是這樣分開做兩次封裝的,傳入的參數(shù)是什么類型,執(zhí)行的語句中參數(shù)就是什么類型;

綜上,執(zhí)行的sql語句要嚴(yán)格按照標(biāo)準(zhǔn)規(guī)范來寫,不同的東西效果肯定不一樣。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容