数据库事务隔离级别详解

来源:互联网 发布:网络金融营销普遍 编辑:程序博客网 时间:2024/06/05 13:27

数据库事务隔离级别详解

--数据库的并发问题
        在介绍数据库事务隔离级别之前先了解一下数据库可能出现的并发问题:
         脏读(Drity Read):T1事务已更新一份数据,T2事务在此时读取了同一份数据,由于某些原因,T1事务执行了一个RollBack了操作,这时T2事务所读取的数据将与数据库中的数据产生不一致,即:T2读取了错误的数据。

         不可重复读(Non-repeatable read):同一个事务的两次查询相同数据,两次查询所获得的数据不一致。事务T1读取数据后,事务T2执行了更新操作(此处更新泛指:增加、删除、修改),使得T1无法再现前一次读取的结果(同一条SQL语句查询结果不一样了)。

丢失修改(Lost Update):两个事务T1和T2读入同一数据并修改,T2提交的结果破坏了T1提交的结果,导致T1的修改被丢失。例如:在一个售票系统中的序列活动顺序:

①:甲售票点(T1事务)读出现在数据库中余票数为A,假设A=16;

②:乙售票点(T2事务)读出现在数据库中余票数为A,也为A=16,同时读取到;

③:甲售票点卖出一张票,修改余票数量为A=A-1,此时A=15写回数据库中;

  ④:乙售票点也卖出了一张票,修改余票数量A=A-1,此时A=15写回数据库;

上面的活动时序图中T1的修改就丢失了(T2事务覆盖了T1事务),导致了数据库中数据的不一致性。

幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。

(幻读可以划归在不可重复读中,相当于不可重复读中另一个事务执行了删除或增加操作)
      

--数据库事务隔离级别   

 SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。不同隔离级别采取不同的锁类型来实现。
Read Uncommitted(读取未提交内容)
       在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。
Read Committed(读取提交内容)
       这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。
Repeatable Read(可重读)
       这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。
Serializable(可串行化) 
       这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

事务的隔离级别要得到底层数据库引擎的支持,而不是应用程序或者框架的支持.

  

Oracle支持的2种事务隔离级别:READ_COMMITED, SERIALIZABLE

         在MySQL中,实现了这四种隔离级别,分别有可能产生问题如下所示:


0 0
原创粉丝点击