zoukankan      html  css  js  c++  java
  • MySQL 并发事务问题以及事务的隔离级别

    一、并发事务处理带来的问题

      相对于串行处理,并发事务(InnoDB)处理能大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,从而可以支持更多用户。

      但并发事务处理也会带来一些问题,主要有一下几种情况:

      更新丢失(Lost Update)

      两个或者多个事务同时选择同一行数据,都基于最初选定的值更新该行,由于每个事务都不知道其它事务的存在,就会发生更新丢失的问题——最后提交的更新覆盖了之前其它事务所做的更新。

      脏读(Dirty Reads)

      一个事务正在对一条记录进行修改,这个事务完成并提交前,这条记录的数据就处于不一致的状态。此时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,并依据此做了进一步的处理,就会产生对未提交的数据的依赖关系。这种现象就叫做“脏读”。

      不可重复读(Non-Repetable Reads)

      一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现读出的数据已经发生了改变、或者某些记录已经被删除了!这种现象叫“不可重复读”。

      幻读(Phantom Reads)

      一个事务按相同的查询条件重新读取以前检索过的数据,却发现其它事务插入了满足其查询条件的新数据。这种现象叫“幻读”。

    二、事务的隔离级别

      上述提到的并发事务处理带来的问题,“更新丢失”是应该完全避免的。

      防止更新丢失,不能单单靠数据库事务控制器来解决,需要应用程序对要更新的数据加必要的锁来解决,因此,防止更新丢失应该是应用的责任。

      脏读、不可重复读和幻读,其实都是数据库读一致性问题,必须由数据库提供一定的事务隔离机制来解决。数据库实现事务隔离的方式,有以下两种:

      1、在读取数据前,对其加锁,阻止其它事务对数据进行修改。

      2、另一种是不用加任何锁,通过一定的机制生成一个数据请求时间点的一致性数据快照,并用这个快照来提供一定级别(语句级别或者事务级别)的一致性读取。从用户的角度看,就好像数据库可以提供同一数据的多个版本,因此这种技术叫做数据多版本并发控制(MVCC)或多版本数据库。

      数据库的事务隔离越严格,并发副作用越小,但是付出的代价越大。因为事务隔离实质上是让事务在一定程度上“串行化”进行,这显然与并发是矛盾的。同时,不同的应用对读一致性和事务隔离程度的要求也是不同的,比如许多应用对“不可重复读”和“幻读”并不敏感,可能更关心数据并发访问能力。

      为了解决事务“隔离”与“并发”的矛盾,ISO/ANSI SQL92定义了4个事务隔离级别,每个级别的隔离程度不同,允许出现的副作用也不同,应用可以根据自己的业务逻辑要求,通过选择不同的隔离级别来平衡隔离与并发的矛盾。

      4种隔离级别如下图:

      数据库未必就一定实现了上述4个隔离级别,Orcale、SQL Server等各有不同。MySQL支持全部的四个隔离级别,但在具体实现时,有一些特点,比如在一些隔离级别下采用MVCC一致性读,但是某些情况下又不是。

    三、对于InnoDB表的锁问题的小结

      小结:

    • InnoDB的行锁是基于索引实现的,如果不通过索引访问数据,InnoDB会使用表锁;
    • 不同的隔离级别下,InnoDB的锁机制和一致性读策略不同;
    • MySQL的恢复和复制对InnoDB的锁机制和一致性读策略也有较大影响;
    • 锁冲突甚至死锁很难完全避免

      在了解了InnoDB锁特性后,用户可以通过设计和SQL调整等措施减少锁冲突和死锁,包括:

    • 尽量使用较低的隔离级别;
    • 精心设计索引,并尽量使用索引访问数据,是加锁更加精确,从而减少锁冲突的机会;
    • 选择合理的事务大小,小事务发生锁冲突的几率也更小;
    • 给记录集显示加锁时,最好一次性请求足够级别的锁。比如要修改数据的话,最好直接申请排他锁,而不是先申请共享锁,修改时再申请排他锁(这样容易产生死锁);
    • 不同程序访问同一组表时,应该尽量约定以相同的顺序访问各个表,对一个表而言,尽可能以固定的顺序存取表中的行,这样可以大大减少死锁的机会;
    • 尽量用相等条件访问数据,这样可以避免间隙锁对并发插入的影响;
    • 不要申请超过实际需要的锁级别;除非必须,查询时不要显示加锁;
    • 对于一些特定的事务,可以使用表锁来提高处理速度或减少死锁的可能;
  • 相关阅读:
    Java vs Python
    Compiled Language vs Scripting Language
    445. Add Two Numbers II
    213. House Robber II
    198. House Robber
    276. Paint Fence
    77. Combinations
    54. Spiral Matrix
    82. Remove Duplicates from Sorted List II
    80. Remove Duplicates from Sorted Array II
  • 原文地址:https://www.cnblogs.com/bigbigbigo/p/10936714.html
Copyright © 2011-2022 走看看