数据库死锁原理与总结
随着系统业务的不断壮大,服务的并发度也越来越高,为确保多线程高并发的情况下对相同资源操作的数据一致性,采用MySQL锁机制进行数据操作。在这样高并发、高吞吐的系统性能要求情况下,带来的是潜在的数据库死锁问题。倘若出现数据库死锁问题,则会导致资源利用率变低、服务稳定性下降。本文主要针对测试中所了解的一些数据库及死锁相关知识进行了归纳,整理和总结,并结合项目测试发现的死锁问题,描述了解决死锁的几种方法,概述了当前针对死锁测试的方法,以共同学习。
1. 背景知识
MySQL InnoDB如何进行数据读取,什么样的数据读取需要加锁,数据隔离级别是什么样的,什么情况下该使用什么类型的锁,锁定的方式又是什么,在本小节梳理了相关背景知识,解答了以上疑问,以更清晰地了解锁机制及死锁产生的原因。
1.1. MVCC:快照读(Snapshot Read)与当前读(Current Read)
MySQL InnoDB存储引擎,实现的是基于多版本的并发控制协议——MVCC (Multi-Version Concurrency Control) (注:与MVCC相对的,是基于锁的并发控制,Lock-Based Concurrency Control)。其最大的优点是:读不加锁,读写不冲突。在读多写少的OLTP应用中,读写不冲突是非常重要的,极大的增加了系统的并发性能,这也是为什么现阶段,几乎所有的RDBMS,都支持了MVCC。
MVCC读取数据的方式分为快照读和当前读两种方式。快照读:读取指定版本,不需要加锁,如简单的select操作;当前读:读取的是记录的最新版本,并且,当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。如插入、更新、删除操作,均需要进行加锁。之所以将这些操作归为当前读,用更新操作举例,在进行更新操作前,首先会读取当前的待更新数据库字段的值进行返回并加锁(当前读),待MySQL收到这个加锁记录后,才会发起一个update的操作,更新该记录。删除操作同理,插入操作稍有不同,简单地说在执行插入前可能会触发唯一键检查操作,也会进行一个当前读。
1.2. 事务的四种隔离级别
在数据库操作中,为了有效保证并发读取数据的正确性,提出的事务隔离级别。数据库锁也是为了构建这些隔离级别存在的。
隔离级别
脏读(Dirty Read)
不可重复读(NonRepeatable Read)
幻读(Phantom Read)
未提交读(Read uncommitted)
可能
可能
可能
已提交读(Read committed)不可能可能可能可重复读(Repeatable read)不可能不可能可能可串行化(Serializable )不可能不可能不可能
表1 事务隔离级别
未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
可重复读(Repeated Read):在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
原文地址:http://www.phpthinking.com/archives/1664
更多内容,请点击阅读原文!
- 阿里自研分布式强一致关系型数据库——X-DB
- 电磁继电器结构原理
- 无功补偿接触器上接的三根线是什么原理?有什么作用?
- 趣味 | 脑洞大开!这组超炫的数学原理动图,看完还想看!
- 涨知识 | 变频器的原理及应用
- 太有用了!倒车原理动画演示,新手必看
- 奇平视点:《论语》“阳货第十七”的路由原理
- 获奖啦,@“想~”“蒋雨”,请尽快联系我们!
- 食品冷冻冷藏原理及食品腐败变质的原因是什么?
- 女性的乳房会越按摩越大吗?根据医学原理,只有一个解释