数据库的读现象

“读现象”是多个事务并发执行时,在读取数据方面可能碰到的状况。先了解它们有助于理解各隔离级别的含义。其中包括脏读、不可重复读和幻读。

数据库带来的并发问题包括:

1. 脏读

当第二个事务选择其它事务正在更新的行时,会发生未确认的相关性问题。第二个事务正在读取的数据还没有确认并且可能由更新此行的事务所更改。

举例1:e.g.

  1. Mary的原工资为1000, 财务人员将Mary的工资改为了8000(但未提交事务)
  2. Mary读取自己的工资 ,发现自己的工资变为了8000,欢天喜地!
  3. 而财务发现操作有误,回滚了事务,Mary的工资又变为了1000

像这样,Mary记取的工资数8000是一个脏数据。

解决办法:如果在第一个事务提交前,任何其他事务不可读取其修改过的值,则可 以避免该问题。

举例2:又如:

这里写图片描述

在这个例子中,事务2回滚后就没有id是1,age是21的数据了。所以,事务一读到了一条脏数据。

2. 不可重复读

不可重复读,是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。这是由于查询时系统中其他事务修改的提交而引起的。比如事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便得到了不同的结果。

一种更易理解的说法是:在一个事务内,多次读同一个数据。在这个事务还没有结束时,另一个事务也访问该同一数据。那么,在第一个事务的两次读数据之间。由于第二个事务的修改,那么第一个事务读到的数据可能不一样,这样就发生了在一个事务内两次读到的数据是不一样的,因此称为不可重复读,即原始读取不可重复。

**举例1:**e.g.

  1. 在事务1中,Mary 读取了自己的工资为1000,操作并没有完成
  2. 在事务2中,这时财务人员修改了Mary的工资为2000,并提交了事务.
  3. 在事务1中,Mary 再次读取自己的工资时,工资变为了2000

解决办法:如果只有在修改事务完全提交之后才可以读取数据,则可以避免该问题。

又如:

举例说明2:

在基于锁的并发控制中“不可重复读(non-repeatable read)”现象发生在当执行SELECT 操作时没有获得读锁(read locks)或者SELECT操作执行完后马上释放了读锁; 多版本并发控制中当没有要求一个提交冲突的事务回滚也会发生“不可重复读(non-repeatable read)”现象。

这里写图片描述

在这个例子中,事务2提交成功,因此他对id为1的行的修改就对其他事务可见了。但是事务1在此前已经从这行读到了另外一个“age”的值。

3. 幻读

例子1:

当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。事务第一次读的行范围显示出其中一行已不复存在于第二次读或后续读中,因为该行已被其它事务删除。同样,由于其它事务的插入操作,事务的第二次或后续读显示有一行已不存在于原始读中。

举例1:  e.g. 目前工资为1000的员工有10人。
  
1. 事务1,读取所有工资为1000的员工。
2. 这时事务2向employee表插入了一条员工记录,工资也为1000
3. 事务1再次读取所有工资为1000的员工 共读取到了11条记录,

解决办法:如果在操作事务完成数据处理之前,任何其他事务都不可以添加新数据,则可避免该问题

例子2:

当事务1两次执行SELECT … WHERE检索一定范围内数据的操作中间,事务2在这个表中创建了(如INSERT)了一行新数据,这条新数据正好满足事务1的“WHERE”子句。

这里写图片描述

在这个例子中,事务一执行了两次相同的查询操作。但是两次操作中间事务二向数据库中增加了一条符合事务一的查询条件的数据,导致幻读。

4.丢失更新

当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题。每个事务都不知道其它事务的存在。最后的更新将重写由其它事务所做的更新,这将导致数据丢失。  
 
e.g.
事务A和事务B同时修改某行的值

  1. 事务A将数值改为1并提交
  2. 事务B将数值改为2并提交。

这时数据的值为2,事务A所做的更新将会丢失。

解决办法:对行加锁,只允许并发一个更新事务。

原文参考:

http://www.hollischuang.com/archives/900

http://blog.csdn.net/d8111/article/details/2595635

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值