?本篇文章给大家带来的内容是关于MySQL数据库的事务隔离和MVCC的详细介绍(图文),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
本篇文章给大家带来的内容是关于MySQL数据库的事务隔离和MVCC的详细介绍(图文),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 前言:事务是访问数据库的一个操作序列,数据库应用系统通过事务集来完成对数据库的存取. 1. 什么是事务? 事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)的缩写,这四种状态的意思是: 2. 事务的作用 当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性. 3. 遇到的并发问题 1.第一类丢失更新:A事务撤销时,把已经提交的B事务的更新数据覆盖了. 4. 如何解决上面的问题呢? 为了解决上面的问题,开发者为MySQL数据库设计了以下四种事务隔离级别: 2.Read Committed(提交读):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读). 3.Repeated Read(可重复读):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读,但是innoDB解决了幻读. 4.Serializable(串行读):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞.
5. 小尝试1.查看全局或会话的事务隔离级别 SELECT @@global.tx_isolation, @@tx_isolation; 2.修改全局或会话的事务隔离级别 SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE] 6. MySQL默认Repeated Read隔离级别,按道理并不能解决幻读问题呀?以下将先介绍数据库所涉及的锁. 7. 锁的基本叙述1.锁简介
针对同一块数据,多个读操作可以同时进行而不会互相影响。共享锁只针对UPDATE时候加锁,在未对UPDATE操作提交之前,其他事务只能够获取最新的记录但不能够UPDATE操作。
当前写操作没有完成前,阻断其他写锁和读锁。
开销大,加锁慢,会出现死锁,锁定力度最小,发生锁冲突的概率最低,并发度高。
开销小,加锁快,不会出现死锁,锁定力度大,发生冲突所的概率高,并发度低。
开销和加锁时间介于表锁和行锁之间,会出现死锁,锁定力度介于表和行行级锁之间,并发度一般。 8. 悲观锁和乐观锁8.1 悲观锁1.基本思想:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁.所以不管冲突是否真的发生,都会使用锁机制。
8.2 乐观锁1.基本思想:总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量. 8.3 版本号机制一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。 8.4 CAS算法1.核心思想:Compare and Swap,即比较再交换。 9. 回到MySQL的重复读(Repeated Read)事务隔离级别前面说过,MySQL默认实现了可重复读的事务隔离级别,但是不能解决幻读的问题,然而在MySQL数据库使用可重复读的事务隔离条件下,并未发生幻读.MySQL使用MVCC(多版本并发控制)进行了控制. 9.1名词简析:1.MVCC:是multiversion concurrency control的简称,也就是多版本并发控制,是个很基本的概念。MVCC的作用是让事务在并行发生时,在一定隔离级别前提下,可以保证在某个事务中能实现一致性读,也就是该事务启动时根据某个条件读取到的数据,直到事务结束时,再次执行相同条件,还是读到同一份数据,不会发生变化(不会看到被其他并行事务修改的数据)。 9.2 Read view详析InnoDB支持MVCC多版本控制,其中READ COMMITTED和REPEATABLE READ隔离级别是利用consistent read view(一致读视图)方式支持的。所谓的consistent read view就是在某一时刻给事务系统trx_sys打snapshot(快照),把当时的trx_sys状态(包括活跃读写事务数组)记下来,之后的所有读操作根据其事务ID(即trx_id)与snapshot中trx_sys的状态做比较,以此判断read view对事务的可见性。 9.3 read view 判断当前版本数据项是否可见在InnoDB中,创建一个新事务的时候,InnoDB会将当前系统中的活跃事务列表(trx_sys->trx_list)创建一个副本(read view),副本中保存的是系统当前不应该被本事务看到的其他事务id列表。当用户在这个事务中要读取该行记录的时候,InnoDB会将该行当前的版本号与该read view进行比较。 从该行记录的DB_ROLL_PTR指针所指向的回滚段中取出最新的undo-log的版本号的数据,将该可见行的值返回。 函数:read_view_sees_trx_id。 read_view中保存了当前全局的事务的范围: 【low_limit_id, up_limit_id】 1.当行记录的事务ID小于当前系统的最小活动id,就是可见的。 if (trx_id < view->up_limit_id) { return(TRUE); } 2.当行记录的事务ID大于当前系统的最大活动id(也就是尚未分配的下一个事务的id),就是不可见的。 if (trx_id >= view->low_limit_id) { return(FALSE); } 3.当行记录的事务ID在活动范围之中时,判断是否在活动链表中,如果在就不可见,如果不在就是可见的。 for (i = 0; i < n_ids; i++) { trx_id_t view_trx_id = read_view_get_nth_trx_id(view, n_ids - i - 1); if (trx_id <= view_trx_id) { return(trx_id != view_trx_id); } } Read view 图解: 结语:笔者水平有限,文中如有不妥,请大家多多指教,MySQL数据库事务机制还有很多需要深入研究的,我们仍需不断钻研。 本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的MySQL视频教程栏目! 以上就是MySQL数据库的事务隔离和MVCC的详细介绍(图文)的详细内容,更多请关注模板之家(www.mb5.com.cn)其它相关文章! |