`
JaHunter
  • 浏览: 92047 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

脏读、不可重复读和虚读

    博客分类:
  • java
阅读更多
脏读 dirty reads:当事务读取还未被提交的数据时,就会发生这种事件。举例来说:Transaction 1 修改了一行数据,然后 Transaction 2 在 Transaction 1 还未提交修改操作之前读取了被修改的行。如果 Transaction 1 回滚了修改操作,那么 Transaction 2 读取的数据就可以看作是从未存在过的。     
不可重复的读 non-repeatable reads:当事务两次读取同一行数据,但每次得到的数据都不一样时,就会发生这种事件。举例来说:Transaction 1 读取一行数据,然后 Transaction 2 修改或删除该行并提交修改操作。当 Transaction 1 试图重新读取该行时,它就会得到不同的数据值(如果该行被更新)或发现该行不再存在(如果该行被删除)。     
虚读 phantom read:如果符合搜索条件的一行数据在后面的读取操作中出现,但该行数据却不属于最初的数据,就会发生这种事件。举例来说:Transaction 1 读取满足某种搜索条件的一些行,然后 Transaction 2 插入了符合 Transaction 1 的搜索条件的一个新行。如果 Transaction 1 重新执行产生原来那些行的查询,就会得到不同的行。


事务场景是这样的:
对于同一个银行帐户A内有200元,甲进行提款操作100元,乙进行转帐操作100元到B帐户。如果事务没有进行隔离可能会并发如下问题:
1、第一类丢失更新:首先甲提款时帐户内有200元,同时乙转帐也是200元,然后甲乙同时操作,甲操作成功取走100元,乙操作失败回滚,帐户内最终为200元,这样甲的操作被覆盖掉了,银行损失100元。
2、脏读:甲取款100元未提交,乙进行转帐查到帐户内剩有100元,这是甲放弃操作回滚,乙正常操作提交,帐户内最终为0元,乙读取了甲的脏数据,客户损失100元。
3、虚读:和脏读类似,是针对于插入操作过程中的读取问题,如丙存款100元未提交,这时银行做报表进行统计查询帐户为200元,然后丙提交了,这时银行再统计发现帐户为300元了,无法判断到底以哪个为准?
大家好像觉得统计这个东西肯定是时时更新的,这种情况很正常;但是如果统计是在一个事务中的时候就不正常了,比如我们的一个统计应用需要将统计结果分别输出到电脑屏幕和远程网络某台计算机的磁盘文件中,为了
提高性能和用户响应我们分成2个线程,这时先完成的和后完成的统计数据就可能不一致,我们就不知道以哪个为准了。
4、不可重复读:甲乙同时开始都查到帐户内为200元,甲先开始取款100元提交,这时乙在准备最后更新的时候又进行了一次查询,发现结果是100元,这时乙就会很困惑,不知道该将帐户改为100还是0。
和脏读的区别是,脏读是读取前一事务未提交的脏数据,不可重复读是重新读取了前一事务已提交的数据。
5、第二类丢失更新:是不可重复读的一种特例,如上,乙不做第二次查询而是直接操作完成,帐户内最终为100元,甲的操作被覆盖掉了,银行损失100元。感觉和第一类丢失更新类似。


在多个事务并发做数据库操作的时候,如果没有有效的避免机制,就会出现种种问题。大体上有三种问题,归结如下:
1、丢失更新
如果两个事务都要更新数据库一个字段X,x=100
事务A             事务B
读取X=100    
                  读取X=100
写入x=X+100
                  写入x=X+200
事务结束x=200
                  事务结束x=300
最后x==300
这种情况事务A的更新就被覆盖掉了、丢失了。
丢失更新说明事务进行数据库写操作的时候可能会出现的问题。
2、不可重复读
一个事务在自己没有更新数据库数据的情况,同一个查询操作执行两次或多次的结果应该是一致的;如果不一致,就说明为不可重复读。
还是用上面的例子
事务A             事务B
读取X=100    
                  读取X=100
读取X=100    
                  写入x=X+100
读取X=200    
事务结束x=200
                  事务结束x=200
这种情况事务A多次读取x的结果出现了不一致,即为不可重复读。
再有一情况就是幻影
事务A读的时候读出了15条记录,事务B在事务A执行的过程中删除(增加)了1条,事务A再读的时候就变成了14(16)条,这种情况就叫做幻影读。
不可重复读说明了做数据库读操作的时候可能会出现的问题。
3、脏读(未提交读)
防止一个事务读到另一个事务还没有提交的记录。
如:
事务A             事务B
                  读取X=100
                  写入x=X+100
读取X=200    
                  事务回滚x=100
读取X=100    
事务结束x=100

x锁 排他锁 被加锁的对象只能被持有锁的事务读取和修改,其他事务无法在该对象上加其他锁,也不能读取和修改该对象
s锁 共享锁 被加锁的对象可以被持锁事务读取,但是不能被修改,其他事务也可以在上面再加s锁。
封锁协议:
一级封锁协议:
在事务修改数据的时候加x锁,直到事务结束(提交或者回滚)释放x锁。一级封锁协议可以有效的防止丢失更新,但是不能防止脏读不可重复读的出现。
二级封锁协议:
在一级封锁的基础上事务读数据的时候加s锁,读取之后释放。二级封锁协议可以防止丢失更新,脏读。不能防止不可重复读。
三级封锁协议:
在一级封锁的基础上事务读数据的时候加s锁,直到事务结束释放。二级封锁协议可以防止丢失更新,脏读,不可重复读。

分享到:
评论

相关推荐

    事务并发处理分析 (举例祥解: 脏读 不可重复的读 虚读)

    5. 第二类丢失更新:是不可重复读的一种特例,如上,乙不做第二次查询而是直接操作完成,账户内最终为 100 元,甲的操作被覆盖掉了,银行损失 100 元。 在多个事务并发做数据库操作的时候,如果没有有效的避免机制...

    Hibernate 事物隔离级别 深入探究

    Serializable 隔离级别可以避免脏读、不可重复读、虚读和第二类丢失更新等问题,但是它的代价是性能开销较高。 二、Repeatable Read 隔离级别 Repeatable Read 隔离级别是第二高级别的隔离级别,它可以避免脏读和...

    MySQL事务的基础学习以及心得分享

    - REPEATABLE READ(可重复读):在同一个事务中多次读取相同数据会得到相同结果,防止脏读和不可重复读,但在某些情况下仍可能出现幻读。 - SERIALIZABLE(串行化):最高的隔离级别,如同操作顺序执行,防止所有...

    数据库事务隔离级别.docx

    数据库事务隔离级别是用来管理多个事务之间相互影响的程度,主要解决的问题包括脏读、不可重复读、幻读等。 #### 二、事务隔离级别的定义与作用 事务隔离级别是指数据库系统为每个事务提供的一种环境,以确保事务在...

    基于框架的Web开发-spring事务入门一个转账的例子.doc

    - **未提交读**:允许脏读、不可重复读、虚读。 - **已提交读**:避免脏读,但可能出现不可重复读和虚读。 - **可重复读**:避免脏读和不可重复读,但可能有虚读。 - **串行化**:完全避免上述所有问题,但性能最低...

    分布式事务解决方案.docx

    脏读、幻读、虚读及不可重复读 - **脏读(Dirty Read)**:一个事务读取到了另一个未提交事务的数据。 - **不可重复读(Non-repeatable Read)**: - **幻读(Phantom Read)**:在事务两次查询期间,其他事务...

    数据库的隔离级别介绍

    它主要解决了并发操作中可能出现的数据不一致性和并发问题,如更新丢失、脏读、不可重复读和虚读。以下是四种标准的事务隔离级别及其特点: 1. 未授权读取(Read Uncommitted): 这是最低的隔离级别,允许脏读取...

    hibernate 对事务并发处理

    3. REPEATABLE_READ:重复读,阻止脏读、不可重复读,发生虚读。 4. SERIALIZABLE:串行处理,不允许两个事务同时操作一个目标数据,根本不存在并发问题(效率低下)。 Hibernate 事务隔离级别 在 Hibernate 中,...

    数据库事务的隔离级别

     不可重复读 与 虚读 的区别:  不可重复读,强调的是,第二次返回的结果中,某个条目被修改过,比如某些字段被修改  虚读,强调的是,第二次返回结果中,属于第一次返回结果的条目没有任何变化,但是返回条目...

    Spring的事务管理以及转账案例

    隔离问题:脏读:一个事务读到另一个事务没有提交的数据不可重复读:一个事务读到另一个事务已提交的数据(update)虚读(幻读):一个事务读到另一个事务已提交的数据(insert)4.隔离级别:readuncommitted:读未...

    Spring中的事务隔离级别的介绍

    * 可重复读(Repeatable Read):避免脏读和不可重复读。但是虚读有可能发生。 * 串行化(Serializable):避免以上所有读问题。 Mysql的默认事务隔离级别是可重复读,而Oracle的默认事务隔离级别是读已提交。 ...

    hibernate框架学习笔记整理

    ### hibernate框架学习笔记整理 #### 一、Hibernate框架简介 ... - 可重复读(Repeatable Read):解决脏读和不可重复读问题。 - 串行化(Serializable):最高隔离级别,解决了所有并发问题,但可能降低性能。

    Java书籍\事务

    为了防止这些事务问题的发生,数据库系统提供了不同的事务隔离级别,包括读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)以及串行化(Serializable)。每种隔离级别都有其...

    database security

    DB2以事务为单位进行并发控制,避免了诸如丢失更新、脏读、不可重复读和虚读等并发操作可能引发的问题。例如,在飞机订票系统的例子中,通过并发控制机制可以防止在高并发情况下出现机票余额计算错误。 **封锁**是...

    MySQL面试题及答案.docx

    7. 脏读、幻读和不可重复读 脏读是指某个事务已更新一份数据,另一个事务在此时读取了同一份数据, 由于某些原因,前一个 RollBack 了操作,则后一个事务所读取的数据就会是不正确的。不可重复读是指在一个事务的两...

    阿里Java面试题集锦

    不同的隔离级别有不同的并发问题,如脏读、不可重复读和虚读(幻读)。 六、常用的中间件: 1. Redis:内存数据存储,提供高速缓存和持久化功能,支持多种数据结构,常用于分布式缓存。 2. Zookeeper:分布式协调...

    Spring+Struts2+Spring3+Hibernate3三大框架整合

    - ISOLATION_xxx:事务隔离级别,如ISOLATION_DEFAULT、ISOLATION_READ_UNCOMMITTED等,用于防止并发问题,如脏读、不可重复读和虚读。 - PROPAGATION_xxx:事务的传播行为,定义了在一个事务方法调用另一个事务...

    java框架-Spring2复习题.doc

    - 事务隔离级别是数据库管理系统提供的功能,用于保证并发操作的正确性,防止诸如更新丢失、脏读、不可重读(包括虚读和幻读)等问题。SQL规范定义了四个事务隔离级别:读未提交、读已提交、可重复读和串行化。 - ...

    10分钟解决Hibernate的事务管理,Hibernate当中要设置事务的隔离级别

    3. 可重复读(Repeatable Read):解决了脏读和不可重复读,但可能有幻读,如MySQL的默认隔离级别。 4. 串行化(Serializable):最高隔离级别,完全避免以上所有问题,但可能导致事务执行效率降低,因为它们必须按...

Global site tag (gtag.js) - Google Analytics