Heim > Datenbank > MySQL-Tutorial > Hauptteil

Mysql并发控制

WBOY
Freigeben: 2016-06-07 15:03:41
Original
1090 Leute haben es durchsucht

最近在看Mysql的并发控制,事务处理等知识,做些整理。 并发控制目的是当多个连接对数据库进行修改时保证数据的一致性。现在mysql的InnoDB在update,delete时使用行级锁,对于select会结合MVCC保证一致性。 1、 并发控制 MySQL提供两个级别的并发控制:服务

最近在看Mysql的并发控制,事务处理等知识,做些整理。

并发控制目的是当多个连接对数据库进行修改时保证数据的一致性。现在mysql的InnoDB在update,delete时使用行级锁,对于select会结合MVCC保证一致性。

1、 并发控制
MySQL提供两个级别的并发控制:服务器级(the server level)和存储引擎级(the storage engine level)。加锁是实现并发控制的基本方法,MySQL中锁的粒度:
(1)    表级锁:MySQL独立于存储引擎提供表锁,例如,对于ALTER TABLE语句,服务器提供表锁(table-level lock)。
(2)    行级锁:InnoDB和Falcon存储引擎提供行级锁,此外,BDB支持页级锁。InnoDB的并发控制机制,下节详细讨论。
另外,值得一提的是,MySQL的一些存储引擎(如InnoDB、BDB)除了使用封锁机制外,还同时结合MVCC机制,即多版本两阶段封锁协议MVCC(Multiversion two-phrase locking protocal),来实现事务的并发控制,从而使得只读事务不用等待锁,提高了事务的并发性。

数据库的事务处理的原则是保证ACID的正确性。

2、事务处理

2.1 事务的ACID特性
事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性:
(1)原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。
(2)一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须是正确的。
(3)隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。
(4)持久性(Durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。

2.2、事务处理带来的相关问题
由于事务的并发执行,带来以下一些著名的问题:
(1)更新丢失(Lost Update):当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题--最后的更新覆盖了由其他事务所做的更新。
(2)脏读(Dirty Reads):一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象地叫做"脏读"。
(3)不可重复读(Non-Repeatable Reads):一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫做“不可重复读”。
(4)幻读(Phantom Reads):一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。


3. Mysql隔离级别:

READ UNCOMMITTED :事务可以看到其他事务没有被提交的数据(脏数据)
READ COMMITTED :事务可以看到其他事务已经提交的数据
REPEATABLE READ :事务中两次查询的结果相同。(Innodb默认级别)
SERIALIZABLE :所有事务顺序执行,对所有read操作加锁。保证一致性。


4. 注意点:

(1)InnoDb通过MVCC防止了幻读(Phantom Read),即两次select之间有另一个事务插入了数据并且commit,两次select也是保证一致性的。但是如果事务B的insert/update/delete语句执行时间和commit时间在本事务A的第一个select之前,则事务A的第一个select是可以读到事务B的更新数据的。


(2)如果一个事务A,先进行了update/insert/delete操作,在进行第一次select操作,那么select是可以读到更新的时间,这样造成的结果是select可能读到根本不存在的数据(http://dev.mysql.com/doc/refman/5.1/en/innodb-consistent-read.html


(3)如果一个事务A进行了select操作,那么在这个select开始后的其他事务B进行了对数据的更新操作(update/insert/delete),事务A的select将不会看到事务B操作的结果。事务Aselect在遍历过程中会遇到两种情况,一种是当前遍历的行时正在被更新(update/insert/delete),那么这一行会被加上write lock锁。另一种是,当前遍历的行没有被加锁。


对于第一种请,Innodb处理方式是select过程中出逐行遍历数据,如果某一行被write lock了,那么会去undo段里面找这一行的前一个snapshot数据,这个snapshot数据是由write操作引起的,每次write操作都将保存当前事务时刻的原始数据,用于write失败进行回滚,所以是放在undo数据段里面。


对于第二种情况:可以通过事务的编号进行过滤,innodb的每个事务都有个事务编号保存在每一行数据的隐藏字段里,如果当前事务编号比数据记录里面的隐藏字段的事务编号小,那么表示当前数据是被当前事务后面的事务更新的,那么不取当前数据,而是去undo段里取snapshot数据。

(Mysql文档的原文是:Suppose that you are running in the default REPEATABLE READ isolation level. When you issue a consistent read (that is, an ordinary SELECT statement), InnoDB gives your transaction a timepoint according to which your query sees the database. If another transaction deletes a row and commits after your timepoint was assigned, you do not see the row as having been deleted. Inserts and updates are treated similarly.)

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!