隔离级别 
=========================



隔离级别定义 
---------------

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 隔离级别。
  

* 跨租户事务

  由于当前有一些内部表尚未拆分到普通租户下，OCP 有可能存在跨租户的事务。在可串行化隔离级别下不允许执行跨租户的事务。
  



