事务隔离级别

Posted by arnkore on March 31, 2017

事务隔离级别

事务分为4种隔离级别:读未提交(RU)、读已提交(RC)、可重复读(RR)、串行读(S)

  • TRANSACTION_READ_UNCOMMITTED:会导致脏读、不可重复读、幻读
  • TRANSACTION_READ_COMMITTED:会导致不可重复读、幻读
  • TRANSACTION_REPEATABLE_READ:会导致幻读
  • TRANSACTION_SERIALIZABLE

导致数据不一致的几种现象

脏读(dirty-read)

一个事务能读取到另一个事务未提交的修改。

  • This level allows a row changed by one transaction to be read by another transaction before any changes in that row have been committed (a “dirty read”). If any of the changes are rolled back, the second transaction will have retrieved an invalid row.

不可重复读(nonrepeatable-read)

记录被事务A读取,此后该记录又被事务B修改掉,事务A又重新去读取该记录,发现跟上一次读取到的值不一致。注意,事务A读取到的是事务B已提交的修改。

  • one transaction reads a row, a second transaction alters the row, and the first transaction rereads the row, getting different values the second time (a “non-repeatable read”).

幻读(phantom-read)

事务A执行满足某个 where 条件的查询,事务B插入了一条满足同样 where 条件的记录,事务A重新执行满足该where条件的查询,会查询到刚刚插入的幻读记录。

  • one transaction reads all rows that satisfy a WHERE condition, a second transaction inserts a row that satisfies that WHERE condition, and the first transaction rereads for the same condition, retrieving the additional “phantom” row in the second read.

java.sql.Connection 里面对于这4种隔离级别的解读

/**
 * A constant indicating that
 * dirty reads, non-repeatable reads and phantom reads can occur.
 * This level allows a row changed by one transaction to be read
 * by another transaction before any changes in that row have been
 * committed (a "dirty read").  If any of the changes are rolled back,
 * the second transaction will have retrieved an invalid row.
 */
int TRANSACTION_READ_UNCOMMITTED = 1;

/**
 * A constant indicating that
 * dirty reads are prevented; non-repeatable reads and phantom
 * reads can occur.  This level only prohibits a transaction
 * from reading a row with uncommitted changes in it.
 */
int TRANSACTION_READ_COMMITTED   = 2;

/**
 * A constant indicating that
 * dirty reads and non-repeatable reads are prevented; phantom
 * reads can occur.  This level prohibits a transaction from
 * reading a row with uncommitted changes in it, and it also
 * prohibits the situation where one transaction reads a row,
 * a second transaction alters the row, and the first transaction
 * rereads the row, getting different values the second time
 * (a "non-repeatable read").
 */
int TRANSACTION_REPEATABLE_READ  = 4;

/**
 * A constant indicating that
 * dirty reads, non-repeatable reads and phantom reads are prevented.
 * This level includes the prohibitions in
 * <code>TRANSACTION_REPEATABLE_READ</code> and further prohibits the
 * situation where one transaction reads all rows that satisfy
 * a <code>WHERE</code> condition, a second transaction inserts a row that
 * satisfies that <code>WHERE</code> condition, and the first transaction
 * rereads for the same condition, retrieving the additional
 * "phantom" row in the second read.
 */
int TRANSACTION_SERIALIZABLE     = 8;