前段时间,阿芬在公司开发的时候,不小心造成了数据库锁表的操作。为了解决问题,我研究了这部分的内容,所以决定把这部分的知识分享给大家。在数据库锁机制方面,如果简单的说“锁表”,总让人觉得有些Low,我们直接换成更高的名词,锁机制!为了保证数据的完整性,也就是它的一致性和有效性,所以数据库才有了锁机制。与其他数据库相比,MySQL的锁机制相对简单。它最显着的特点是不同的存储引擎支持不同的锁机制。MyISAM和MEMORY存储引擎使用表级锁定。BDB存储引擎使用页级锁定,也支持表级锁定。InnoDB存储引擎支持行级锁定。),也支持表级锁。我们先来看看这些锁是什么鬼!行级锁(row-levellocking)锁的对象粒度非常小,各大数据库中锁粒度最小的锁资源占用概率最小。虽然行级锁的优点很明显,但是相对的缺点也因为它的优点而显现出来。因为加锁的粒度比较小,每次获取和释放锁需要做的内容比较多,造成的消耗肯定比较大,行级锁也是最容易出现死锁的。并发度也是最高的。表级锁与行锁相反。粒度是最大的。逻辑简单,对系统的负面影响比较小。获取和释放锁的速度很快。并发度最低。缺点也有,因为粒度比较大,锁定资源的概率会高。页级锁比较特殊,介于行锁和表锁之间,所以它的能力介于两者之间。它们之间的区别是表级锁的粒度>页锁>行锁,它的并发度一般。但是他会有僵局。三者之中,好像只有表锁是不会死锁的。到这里我们已经对锁机制有了一个大概的了解。让我们仔细看看表锁。表锁其实分为两种,读锁和写锁。这两种类型的锁都是通过它们内部的队列来锁定的。为了维护,当前读锁队列(Currentread-lockqueue)挂起读锁队列(Pendingread-lockqueue)挂起写锁队列(Pendingwrite-lockqueue)当前写锁队列(Currentwrite-lockqueue))这是什么意思?当前读锁队列实际上包含了当前持有读锁的所有线程。存储的是等待获取结果的线程。大家肯定知道writelock是什么意思,就像一个4*100的接力赛。拿着“棒子”的是当前的读写锁队列,等待接收“棒子”的是待处理的读写锁队列。行锁MySQL的InnoDB存储引擎支持行级锁,InnoDB的行锁是通过加锁索引条目来实现的。这句话是什么意思?它意味着一件事:InnoDB只有在通过索引条件检索数据时才使用行锁,否则使用表锁。是不是很意外,但事实上确实如此。InnoDB级别的行锁也分为共享锁、排它锁、共享锁和排它锁(SharedandExclusiveLocks)两种。InnoDB以两种方式实现标准行锁:共享锁和排它锁。共享锁(S锁):允许事务获得锁后读取数据,排它锁(X锁):允许事务获得锁后更新或删除数据。一个事务获取共享锁S后,其他事务就可以获取S锁。此时,两个事务都持有共享锁S,但不允许其他事务获取X锁。如果一个事务获得了排他锁(X),其他事务就不允许获得S或X锁。您必须等到事务释放锁后才能获取它。想必很多读者都深有体会,肯定还有其他人,还有意向共享锁和意向排他锁。这种意向共享锁和意向排他锁的意思是,如果我需要共享锁,但是这个共享锁此时正在锁定这个资源,那么我可以自己加一个共享锁,只能等待共享锁来被发布。这种锁可以称为意向共享锁。同样,排他锁也是一样的。而它们之间的逻辑关系是这样的。其实数据库锁表最简单的原因就是它会出现在insert、update、delete操作的并发操作中。当我们使用多个数据库连接,同时更新一个表中的数据时,那么速度就会相应变慢。如果持续一段时间,就会出现锁表的现象。那么哪些操作会导致表锁呢?(1)插入查询语句insertintotablevaluesselectxxxxfromtable2,会锁定table2。(2)这样更新并发操作updatetable1table2settable1.name='xxx'wheretable1.id=table2.id也会造成表锁。如何减少锁表的情况?MyISAM表锁优化:缩短加锁时间:这么说吧,最简单的就是加个索引,让你的索引利用率最大化。合理使用读写优先级:写入优先,读取次之。Innodb行锁的优化添加索引,让查询走索引学会控制事务隔离级别不要随便设置,根据不同情况选择即可
