一、并发性带来的问题
多用户对数据库的并发访问带来几个问题,如脏读(dirty read)、幻读(phantom read)、更新丢失(lost update)和不可重复读(nonrepeatable read)。
1、脏读
当一个事务读取另一个正在进行的事务更新但未永久提交到数据库的数据时,发生脏读。
2、幻读
假如你正从一个表读数据(select),一段时间后,又重新执行一遍查询,这时,其他用户已经插入新数据到表中。第二次查询遇到第一次读时没有的行,这就是"幻读"。幻读问题是由一个事务的两个数据库操作之间出现新数据而导致的。
3、更新丢失
更新丢失问题是由某事务试图在数据被其他事务更新时读取它导致的问题。假如事务A正在读一个表的数据,而此数据正被事务B更新,事务B成功完成并提交。如果事务A在事务B成功完成前已经读取数据,则它读取的可能是中间数据。由于两个用户更新了相同的行,并且第二次更新覆盖了第一次的更新,则第一个更新丢失,此时这种不正常的丢失更新便出现了。这是一个事务完成之前允许其他事务读和更新一个表所引起的问题。
4、不可重复读
当一个事务发现它以前读的数据已经被其他事务修改,不可重复读问题就产生了。假如你在某个时间点访问了一个表的数据,稍后又试图访问相同的数据,发现第二次读的数据与第一次的不同了。这种相同事务中不一致的数据导致不可重复读问题。
二、Oracle的隔离级别
1、串行
在隔离的串行级别下,所有事务相互之间完全隔离,就好像事务处理以串行方式一个接一个地执行一样。在隔离的串行级别下,执行插入、删除、更新或更新的事务在受DML操作影响的一组数据上放置一个写锁。在隔离事务释放其锁之前,即在该事务处理被提交或回滚时,数据库锁定受影响的数据。由于涉及DML操作的其他事务不得不等待锁解除,故那些事务不会读任何“脏”数据。隔离的串行级别还帮助你避免不可重复读,因为随后的事务处理不能更新或删除锁定的数据。由于后面的事务处理不能在第一个事务处理锁定的数据范围内插入任何新行,从而摆脱了幻读数据。
2、可重复读
可重复读隔离级别保证读一致性,即一个事务在两个不同的时间点从一个表中读数据两次,每次都得到相同的值。这个级别的隔离避免了脏读和不可重复读问题。
3、未提交读
未提交读级别允许事务读取其他事务未提交前的中间值,它可能会导致并发使用的所有问题。
4、已提交读
Oracle的默认隔离级别是语句级的已提交读隔离级别。Oracle查询只能看到查询开始时已提交的数据。因为此隔离级别是语句级的,所以每条语句只允许看到该语句开始前已经提交的数据。隔离的已提交读级别保证在访问Oracle表中特定的行时,该行的数据不会改变。
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
未提交读 | 是 | 是 | 是 |
已提交读 | 否 | 是 | 是 |
可重复读 | 否 | 否 | 是 |
串行 | 否 | 否 | 否 |