首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

MySQL索引底层(三)--InnoDB中的锁

行锁,表锁

InnoDB存储引擎中有行锁以及表锁,行锁是InnoDB中默认的锁。

表锁:对整张表进行加锁,在同一时刻整张表的所有记录都被锁住。

行锁:只对表中的某一行记录进行加锁,表的其余行不会被占用,但是可能会出现死锁。

关闭事务自动提交

查看一下表数据

接着我们更新一条数据

执行成功之后我们并没有提交事务,这个时候这一条记录已经是加了锁的,所以我们在另外一个客户端更新同样的行记录。

自然就报错了,直接就等待超时了。这里证明已经加锁了,接着我们来证明是行锁还是表锁。

当我们执行update的时候,是update 字段a=1的 所以我们在update字段a=2的时候,虽然没有提交事务但是还是可以执行的,这里证明了InnoDB是行锁的。

注意:行锁必须有索引才能实现,否则就会自动锁住全表,也就是表锁,而InnoDB当有主键的时候,自动就会创建主键索引。

行锁与表锁的区别

行锁

优点 :粒度小, 因为加锁的只是一行数据。

缺点 :获取、释放所需要做的工作更多,并且容易发生死锁。

锁的优化:

合理设计索引

减少基于范围的数据检索过滤条件

尽量控制事务的大小,尽量使用较低的事务隔离级别

尽可能让所有的数据检索都通过索引来完成。

表锁

优点:获取跟释放快,能避免死锁(当执行update语句的时候,把整个表锁住了,其他的sql无法执行,所以不会造成死锁)

缺点:粒度太大,并发不够高,当并发量较多的时候,锁表会让进程无法继续执行sql。

死锁

死锁出现在行锁中,假设现在有一个T1的session线程去update一个数据库表table1 ,而且有一个T2的session线程去update一个数据库表table2。

在没有提交事务的时候,table1跟table2都已经进行了加锁,这个时候,T1去操作了table2,那么这个时候因为table2的记录加了锁,那么T1会一直在等待,接着T2又同样的去操作table1的表记录,也同样在等待,就造成了死锁

举报
领券