索引对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字段是否加索引。接口

相关文章
相关标签/搜索