索引對mysql行鎖和表鎖影響

一、前言

昨天生產環境遇到了一個比較詭異的問題,project a 調用 project b webservice,b webservice在作insert操做的時候數據庫報以下錯誤。mysql

lock wait timeout exceeded; try restarting transaction

 

二、緣由分析

從報錯信息分析應該是project b在進行insert操做的時候操做的表被鎖住了, project b的全部數據庫操做都是在同一事務上,原則上不會出現鎖表的狀況,由此推出應該是project a 在調用project b接口的時候尚未提交事務,而且對同一張表執行了update操做並鎖住了整張表。web

三、經過數據庫還原整個場景。

相關表:t_product_base  id,name(未作索引)sql

第一步:根據name對product進行update操做數據庫

begin;
update t_product_base set name = 'fengshuzi' where name = 'fengshuzi'

第二步:新開一個事務進行update操做spa

begin;
update t_product_base set name = '318' where name='317';
commit;

第三步:報錯以下rest

 

四、緣由分析

第一步對product表進行update操做暫不提交事務,where條件使用的是name,由於name沒有作索引,此時update操做會鎖住整張表,在第一步的事務沒有提交以前其餘事務沒法對鎖住的表進行update操做只能等待。code

如若想要使得以上操做成功須要給name字段加上索引這樣在執行第一步的sql的時候mysql鎖住的是name=‘xxx’相關的行而不是整張表,這樣的話其它事務能夠操做product表的其它行。索引

 

五、總結

咱們在進行擴項目操做數據庫的時候須要特別注意數據庫事務鎖的問題。update操做鎖住的是表仍是行關鍵要看update後面的where字段是否加索引。接口

相關文章
相關標籤/搜索