Windows Defender 垃圾?
面试官: 你前面说到的锁可以解决事务并发,然而MVCC也是用于解决并发,那干嘛还用锁来呢?你给说说 吒吒辉: 通过MVCC可以解决脏读、不可重复读、幻读这些读一致性问题,但实际上这只是解决了普通select语句的数据读取问题。 事务利用MVCC进行的读取操作称之为快照读,所有普通的SELECT语句在READ COMMITTED、REPEATABLE READ隔离级别下都算是快照读。 除了快照读之外,还有一种是锁定读,即在读取的时候给记录加锁,在锁定读的情况下依然要解决脏读、不可重复读、幻读的问题。 比如:如果 1 4 7 9 的数据。如果条件为 where > 4 的,那如果不锁定到 (4,7] (7,9],(9,+∞)。那势必就会早幻读,不可重复读的问题。 ps:不重复读?脏读是如何产生的? 死锁 面试官: 那你说下数据库的死锁是个什么情况? 吒吒辉: 死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环。 当事务试图以不同的顺序锁定资源时,就可能产生死锁。多个事务同时锁定同一个资源时也可能会产生死锁。 一般可通过死锁检测和死锁超时机制来解决该问题。 死锁检查: 像InnoDB存储引擎,就能检测到死锁的循环依赖,并立即返回一个错误。否则死锁会导致出现非常慢的查询。通过参数 innodb_deadlock_detect 设置为on,来开启。 超时机制: 就是当查询的时间达到锁等待超时的设定后放弃锁请求。InnoDB目前处理死锁的方法是,将持有最少行级排他锁的事务进行回滚(这是相对比较简单的死锁回滚算法)。 可通过配置参数 innodb_lock_wait_timeout 用来设置超时时间。如果有些用户使用哪种大事务,就设置锁超时时间大于事务执行时间。 但这种情况下死锁超时检查的发现时间是无法接受的。 面试官: 那你说说InnoDB和MyisAM是如何发现死锁的? 吒吒辉:
数据库会把事务单元锁维持的锁和它所等待的锁都记录下来,Innodb提供了wait-for graph算法来主动进行死锁检测,每当加锁请求无法立即满足需要进入等待时,wait-for graph算法都会被触发。当数据库检测到两个事务不同方向地给同一个资源加锁(产生循序),它就认为发生了死锁,触发wait-for graph算法。 比如:事务1给A加锁,事务2给B加锁,同时事务1给B加锁(等待),事务2给A加锁就发生了死锁。那么死锁解决办法就是终止一边事务的执行即可,这种效率一般来说是最高的,也是主流数据库采用的办法。 Innodb目前处理死锁的方法就是将持有最少行级排他锁的事务进行回滚。这是相对比较简单的死锁回滚方式。死锁发生以后,只有部分或者完全回滚其中一个事务,才能打破死锁。 对于事务型的系统,这是无法避免的,所以应用程序在设计必须考虑如何处理死锁。大多数情况下只需要重新执行因死锁回滚的事务即可。
MyisAM自身只支持表级锁,故加锁后一次性获取的。所以资源上不会出现多个事务之间互相需要对方释放锁之后再来进行处理。故不会有死锁 面试官: wait-for graph 算法怎么理解?
吒吒辉: 如下所示,四辆车就是死锁 (编辑:长春站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |