Herong's Tutorial Notes on SQL
Dr. Herong Yang, Version 3.02

Transaction Management

Part:   1  2  3   4 

(Continued from previous part...)

Transaction Isolation Levels

As we can see from previous sections, the impact of a transaction in the current session is simple. However, concurrent transactions in multiple sessions may impact each other in many ways. Three phenomena have been observed in concurrent transactions:

  • Dirty Read - One transaction T1 reads uncommitted changes from another transaction T2. If T2 performs a rollback later, T1 may have used incorrect data from the uncommitted changes.
  • Non-Repeatable Read - One transaction T1 reads a row, which is changed and committed by another transaction T2 later. Now if T1 reads the same row again, the result will be will be different from the first read.
  • Phantom - One transaction T1 reads a set of rows that satisfy a condition. Another transaction T2 then inserts some new rows that satisfy the same condition. If T1 repeats the same read, it will receive some "phantom" rows.

To be able to control and avoid those phenomena, 4 transaction isolation levels have been defined by SQL standards:

  • Read Uncommitted - This is the lowest isolation level. All three phenomena are possible.
  • Read Committed - Dirty Read is prevented. But Non-Repeatable Read and Phantom are possible.
  • Repeatable Read - Dirty Read and Non-Repeatable Read are prevented. But Phantom is still possible.
  • Serializable - This is the highest isolation level. All three phenomena are prevented.

MySQL Support of Transaction Isolation Levels

  • Transaction isolation levels are supported by the InnoDB storage engine.
  • The default isolation level is "Repeatable Read".
  • The SET statement can be used to change the isolation level for the next transaction: "SET TRANSACTION ISOLATION LEVEL level_name".
  • The SET statement can be used to change the isolation level for the entire session, starting with the next transaction: "SET SESSION TRANSACTION ISOLATION LEVEL level_name".

MySQL Transaction Isolation Level Test - Read Uncommitted

To understand better the "Read Uncommitted" isolation level, I did the following test with two command windows.

In the first window, I started "session 1", and issued several statements at different times:

\mysql\bin\mysql test
mysql> SELECT 'Session 1';
+-----------+
| Session 1 |
+-----------+ 
mysql> DROP TABLE IF EXISTS User;
mysql> CREATE TABLE User (ID INT PRIMARY KEY, Name CHAR(8))
   ENGINE=InnoDB;
mysql> START TRANSACTION;
mysql> INSERT INTO User VALUES (2, 'bill');
mysql> SELECT CURRENT_TIME();
+----------------+
| 20:08:40       |
+----------------+
mysql> -- continue with session 2
mysql> SELECT CURRENT_TIME();
+----------------+
| 20:20:57       |
+----------------+
mysql> ROLLBACK;
mysql> -- continue with session 2

In the second window, I started "session 2", and started a transaction with "read uncommitted":

\mysql\bin\mysql test
mysql> SELECT 'Session 2';
+-----------+
| Session 2 |
+-----------+ 
mysql> SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
mysql> START TRANSACTION;
mysql> SELECT CURRENT_TIME();
+----------------+
| 20:17:35       |
+----------------+
mysql> SELECT * FROM User;
+----+------+
|  2 | bill |
+----+------+
mysql> -- continue with session 1
mysql> SELECT CURRENT_TIME();
+----------------+
| 20:23:28       |
+----------------+
mysql> SELECT * FROM USER;
Empty set (0.00 sec)

The result clearly shows that "dirty read" could indeed happen in a transaction with "read uncommitted" isolation level.

(Continued on next part...)

Part:   1  2  3   4 

Dr. Herong Yang, updated in 2006
Herong's Tutorial Notes on SQL - Transaction Management