[TOC] # 隔离级别 ## 隔离级别定义 ANSI 和 ISO/IEC 基于 SQL 标准定义了四种隔离级别,这些隔离级别根据事务并发执行过程中必须防止的现象来定义的。 可预防的异象包括: * 脏读(Dirty Read) 一个事务读到其他事务尚未提交的数据。 * 不可重复读(Non Repeatable Read) 曾经读到的某行数据,再次查询发现该行数据已经被修改或者删除。例如:`select c2 from test where c1=1;`第一次查询`c2`的结果为`1`,再次查询由于其他事务修改了`c2`的值,因此`c2`的结果为`2`。 * 幻象读(Phantom Read) 只读请求返回一组满足搜索条件的行,再次执行发现另一个提交的事务已经插入满足条件的行。 基于上述三种异象定义的四种隔离级别如下: * 读未提交(Read Uncommitted) * 读已提交(Read Committed) * 可重复读(Repeatable Read) * 可串行化(Serializable) OceanBase 数据库的 MySQL Mode 支持读已提交、可重复读两种隔离级别,Oracle Mode 支持读已提交、可重复读和可串行化三种隔离级别。两种模式下,OceanBase 数据库默认的隔离级别是读已提交。 ## 隔离级别设置 **语法** 设置隔离级别有两种方式,分别为事务级别及 Session 级别。 * Transaction level:`SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;` * Session level:`ALTER SESSION SET ISOLATION_LEVEL = SERIALIZABLE;` **注意事项** * 不能在事务执行过程中设置隔离级别,否则会报错。 `ERROR:ORA-01453: SET TRANSACTION must be first statement of transaction` * 在开启可串行化隔离级别时需要确保全局时钟服务(Global Timestamp Service)是打开的。 * Session 需要维护 Session 级别的事务隔离级别,在开启事务时获取 Session 级别的事务隔离级别,该隔离级别可以被事务级别的隔离级别覆盖。 ## 系统限制 * 内部事务 由用户事务触发的内部事务,以及维护内部表信息的事务都称为内部事务,内部事务采用 Read Committed 隔离级别。 * 跨租户事务 在可串行化隔离级别下不允许执行跨租户的事务。