MySQL技术内幕 七:锁(包括乐观悲观锁)(已迁移)

一:锁:

        锁是数据库系统区别于文件系统的一个关键特性,锁机制用于管理对共享资源的并发访问。InnoDB存储引擎会在行级别上对表数据上锁,不过在数据库内部其他地方也使用锁,从而允许对多种不同资源提供并发访问。例如,操作缓冲池中的LRU列表,删除。添加。移动LRU列表中的元素,为了保证一致性,必须有锁介入。锁是为了支持对共享资源的并发访问。innodb不需要锁升级,因为一个锁和多个锁的开销是相同的

    InnoDB存储引擎锁的实现和oracle非常类似,提供一致性的非锁定读。行级锁支持,行级锁没有相关的开销,可以同时得到并发性和一致性

innodb

二:锁的类型:

        1.共享锁(S Lock),允许事务读(同)一行数据。

        2.排他锁(X Lock),允许事务删除或者更新一行数据。

        理解:当一个事务已经获得行r的共享锁,那么另外的事务可以立即获得行r的共享锁,因为读取并没有改变行r的数据,我们称这种情况为锁兼容。但如果有事务想获得行r的排他锁,必须等待事务释放行r的共享锁---------这种情况称为锁不兼容

三:一致性的非锁定读操作:

    一致性的非锁定行读是指InnoDB存储引擎通过多版本并发控制(MVCC)的方式来读取当前执行时间数据库中行的数据。如果读取得行正在执行delete/update操作,这时读取操作不会因此而会等待行上锁的释放,相反,InnoDB会去读取行的一个快照数据。正是因为不需要等待访问的行上x锁的释放,快照数据是指该行之前版本的数据。通过undo段实现,而undo段用来在事务中回滚数据,因此快照数据本身没有额外开销,不需上锁

    理解:对于一致性的非锁定读的快照数据是之前版本的数据,不一定是最新的数据,对于快照数据的定义有几种,一种是最新数据

四:行锁与表锁比较:

       1.表锁:是最基本的锁策略,开销最小,对整张表进行锁定,写锁的优先级比读锁高,写锁可以插入到读锁的队列前面,反之则不行。一个用户在对表进行写操作时(插入、更新、删除等),需要先获得写锁,这会阻塞其他用户对该表的所有读写操作,只有没有写锁时,其他用户才能得到读锁。

       2.行锁:可以最大程度的支持并发(锁定的资源最少),只在存储引擎层实现,而在mysql服务器层没有实现,服务器会为alter table 使用表锁,而忽略存储引擎的锁机制

五:乐观锁与悲观锁:

       悲观锁,也叫悲观并发控制,当事务A对某行数据应用了锁,并且当这个事务把锁释放后,其他事务才能够执行与该锁冲突的操作,这里事务A所施加的锁就叫悲观锁。

看到这里,会发现,我们之前学习的共享锁和排他锁(行锁,间隙锁,next-key lock)都属于悲观锁。

      乐观锁,也叫乐观并发控制,它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各自影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,有没有其他事务又修改了该数据。如果其他事务有更新的话,那么当前正在提交的事务会进行回滚。
悲观锁的实现依靠的是数据库提供的锁机制来实现,例如select * from news where id=12 for update,而乐观锁依靠的是记录数据版本来实现,即通过在表中添加版本号字段来作为是否可以成功提交的关键因素。

根据之前对锁的学习,我们可以大概可以看到innodb下各个锁之间的关系,如图:


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章