数据库频繁更新死锁分析

原因:更新时都是用表锁,或者行锁锁定的行数太多就容易导致长时间的锁等待甚至死锁。

背景知识:数据库在更新时会通过锁的方式防止其他线程更新此记录

    表级锁:锁住整张表

    行级锁:锁住一行或者多行

mysql InnoDB中

    InnoDB行锁是通过给索引上的索引项加锁来实现的。

    只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁

    用主键或者唯一索引来更新(where条件),这样是行锁,否则是表锁

加锁分类

    在不通过索引条件查询的时候,InnoDB使用的是表锁,而不是行锁。

    由于MySQL的行锁是针对索引加的锁,不是针对记录加的锁,所以即使是访问不同行的记   录,如果使用了相同的索引键,也是会出现锁冲突的。

不论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁。

即便在条件中使用了索引字段,但具体是否使用索引来检索数据是由MySQL通过判断不同执行计划的代价来决定的。如果执行计划没走索引,那么就会对表加锁

分析的终极办法:检查SQL的执行计划,以确认是否真正使用了索引。

加锁例子

table:update_table,主键:id,唯一索引index1,普通索引:index2

UPDATE `update_table` SET `num`='1' WHERE id=1  锁一行记录

UPDATE `update_table` SET `num`='1' WHERE index1=1  锁一行记录

UPDATE `update_table` SET `num`='1' WHERE index2=1  锁一行或者多行记录

UPDATE `update_table` SET `num`='1' WHERE a=1  锁整张表

解决办法

1、调整索引:把where语句的的字段加入索引,保证数据库加的是行锁

2、在方法上加上synchronized

你可能感兴趣的:(数据库频繁更新死锁分析)