关系型数据库的隔离级别 读一致性
来自网络:
三种可防止的现象:
脏读(dirty read):事务可以读取其他事务还没有提交的修改;
不可重复读(nonrepeatable read):事务读取先前曾读取过的数据,发现其他的已提交事务修改或删除了要读取的数据;
幻象读(phantom read):事务再次执行一个查询,发现其他已提交事务插入了新的满足当前查询条件的数据。
针对以上三种现象,SQL92标准指定了4种隔离制度,这4种隔离制度一种比一种严格。
Read uncommitted:允许脏读、不可重复读和幻象读;
Read committed:不允许脏读,允许不可重复读和幻象读;
Repeatable read:不允许脏读、不可重复读,允许幻象读;
Serializable:不允许脏读、不可重复读和幻象读。
Oracle提供Read Committed和Serializable隔离等级,还提供了一种额外的只读模式。其中默认采用Read Committed模式。
Oracle 事务隔离级别
Oracle 支持以下三种事务隔离级别(transaction isolation level)。
隔离级别 | 描述 |
已提交读取 | Oracle 默认使用的事务隔离级别。事务内执行的查询只能看到查询执行前(而非事务开始前)就已经提交的数据。Oracle 的查询永远不会读取脏数据(未提交的数据)。 Oracle 不会阻止一个事务修改另一事务中的查询正在访问的数据,因此在一个事务内的两个查询的执行间歇期间,数据有可能被其他事务修改。举例来说,如果一个事务内同一查询执行两次,可能会遇到不可重复读取或不存在读取的现象。 |
串行化 | 串行化隔离的事务只能看到事务执行前就已经提交的数据,以及事务内 INSERT , UPDATE ,及 DELETE 语句对数据的修改。串行化隔离的事务不会出现不可重复读取或不存在读取的现象。 |
只读模式 | 只读事务只能看到事务执行前就已经提交的数据,且事务中不能执行 INSERT , UPDATE ,及 DELETE 语句。 |
我的理解:
Oracle的默认隔离级别只能保证语句级别的读一致性,如果事务执行了一半,其他的事务提交了,这种影响会体现在这个事务往下的查询中的。
Oracle的串行隔离级别是保证了事务级别的读一致性,在整个事务执行期间,只能看到事务开始执行的那个时间点的状态和本事务在执行期间的影响,其他事务即使提交了,也看不到。
网上有文章说,串行化事务应该在什么样的场景去使用,下面摘抄一段:
符合以下特性的系统适合采用串行化隔离(serializable isolation):
1、数据量大,但事务短小,只会更新较少数据行的数据库
2、两个并发事务修改相同数据的概率较小
3、运行时间相对较长的事务只执行只读操作
这一段我看的不太明白,一个是事务级别的读一致性,一个是语句级别的读一致性,适合什么样的场景,应该是看业务场景的严格程度吧。
后来在翻阅ORACLE的概念手册的时候,发现这段话是出自那里的。既然是ORACLE的官网手册的说法,应该是有指导意义的。可能ORACLE的出发点是在对比已提交读隔离级别和串行隔离级别的区别。因为串行隔离级别要会独占数据的更新操作,所以不能又太多的更新操作或者耗时太长的更新操作,以免与其他事务冲突,造成过多等待,影响性能。或者由于独占事务没有识别到其他事务的更新提交操作而造成ORA-08177: 无法进行串行化访问错误。