1. 程式人生 > >Mysql 的事務隔離

Mysql 的事務隔離

測試環境:mysql版本

mysql> select @@version;
+-----------+
| @@version |
+-----------+
| 5.6.42    |
+-----------+
1 row in set (0.00 sec)

mysql>

Mysql的事務隔離

標題


-- read-uncommitted ,讀未提交

--session 1 

mysql> show variables like '%iso%';
+---------------+------------------+
| Variable_name | Value            |
+---------------+------------------+
| tx_isolation  | READ-UNCOMMITTED |
+---------------+------------------+
1 row in set (0.00 sec)

mysql> select * from t1;
+------+-------+------+
| year | month | day  |
+------+-------+------+
| 2000 |    01 |   01 |
| 2000 |    01 |   20 |
| 2000 |    01 |   30 |
| 2000 |    02 |   02 |
| 2000 |    02 |   23 |
| 2000 |    02 |   23 |
| 2018 |    10 |   28 |
| 2018 |    11 |   05 |
| 2018 |    11 |   04 |
| 2018 |    11 |   03 |
| 2018 |    11 |   06 |
| 2018 |    11 |   07 |
+------+-------+------+
12 rows in set (0.00 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values(2018,11,08);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t1;
+------+-------+------+
| year | month | day  |
+------+-------+------+
| 2000 |    01 |   01 |
| 2000 |    01 |   20 |
| 2000 |    01 |   30 |
| 2000 |    02 |   02 |
| 2000 |    02 |   23 |
| 2000 |    02 |   23 |
| 2018 |    10 |   28 |
| 2018 |    11 |   05 |
| 2018 |    11 |   04 |
| 2018 |    11 |   03 |
| 2018 |    11 |   06 |
| 2018 |    11 |   07 |
| 2018 |    11 |   08 |
+------+-------+------+
13 rows in set (0.00 sec)

mysql>

--session 2

mysql> select * from t1;
+------+-------+------+
| year | month | day  |
+------+-------+------+
| 2000 |    01 |   01 |
| 2000 |    01 |   20 |
| 2000 |    01 |   30 |
| 2000 |    02 |   02 |
| 2000 |    02 |   23 |
| 2000 |    02 |   23 |
| 2018 |    10 |   28 |
| 2018 |    11 |   05 |
| 2018 |    11 |   04 |
| 2018 |    11 |   03 |
| 2018 |    11 |   06 |
| 2018 |    11 |   07 |
| 2018 |    11 |   08 |
+------+-------+------+
13 rows in set (0.00 sec)

mysql>


從上面的測試,可以看到,一個事務,並沒有commit提交,在其他的會話中,可以看到這個事務。也就是一個事務可以讀取其他事務沒有提交的資料 。

-- read committed  。類似Oracle的情況

-- session 1 ,插入資料,未提交

mysql> show variables like '%iso%';
+---------------+----------------+
| Variable_name | Value          |
+---------------+----------------+
| tx_isolation  | READ-COMMITTED |
+---------------+----------------+
1 row in set (0.00 sec)

mysql> select * from t1;
+------+-------+------+
| year | month | day  |
+------+-------+------+
| 2000 |    01 |   01 |
| 2000 |    01 |   20 |
| 2000 |    01 |   30 |
| 2000 |    02 |   02 |
| 2000 |    02 |   23 |
| 2000 |    02 |   23 |
| 2018 |    10 |   28 |
| 2018 |    11 |   05 |
| 2018 |    11 |   04 |
| 2018 |    11 |   03 |
| 2018 |    11 |   06 |
| 2018 |    11 |   07 |
+------+-------+------+
12 rows in set (0.00 sec)

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values (2018,11,08);
Query OK, 1 row affected (0.00 sec)

mysql>

-- session 2上檢視  ,沒有讀取到新插入的資料

mysql> select * from t1;
+------+-------+------+
| year | month | day  |
+------+-------+------+
| 2000 |    01 |   01 |
| 2000 |    01 |   20 |
| 2000 |    01 |   30 |
| 2000 |    02 |   02 |
| 2000 |    02 |   23 |
| 2000 |    02 |   23 |
| 2018 |    10 |   28 |
| 2018 |    11 |   05 |
| 2018 |    11 |   04 |
| 2018 |    11 |   03 |
| 2018 |    11 |   06 |
| 2018 |    11 |   07 |
+------+-------+------+
12 rows in set (0.00 sec)

mysql>

-- session 1 提交 ,session 2 再次檢視,發現看到了提交後的資料

mysql> commit;
Query OK, 0 rows affected (0.02 sec)

mysql>

mysql> select * from t1;
+------+-------+------+
| year | month | day  |
+------+-------+------+
| 2000 |    01 |   01 |
| 2000 |    01 |   20 |
| 2000 |    01 |   30 |
| 2000 |    02 |   02 |
| 2000 |    02 |   23 |
| 2000 |    02 |   23 |
| 2018 |    10 |   28 |
| 2018 |    11 |   05 |
| 2018 |    11 |   04 |
| 2018 |    11 |   03 |
| 2018 |    11 |   06 |
| 2018 |    11 |   07 |
| 2018 |    11 |   08 |
+------+-------+------+
13 rows in set (0.00 sec)

mysql>

-- 可重複讀 ,repeatable-read  
-- 是mysql資料庫的預設的事務隔離級別。消除了髒讀,不可重複讀,幻讀,很好地保證了事務的一致性。


-- session 1 ,開啟一個事務,插入資料,並提交資料。

mysql> show variables like '%iso%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tx_isolation  | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.01 sec)


mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values (2018,11,09);
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.11 sec)

mysql>

mysql> select * from t1;
+------+-------+------+
| year | month | day  |
+------+-------+------+
| 2000 |    01 |   01 |
| 2000 |    01 |   20 |
| 2000 |    01 |   30 |
| 2000 |    02 |   02 |
| 2000 |    02 |   23 |
| 2000 |    02 |   23 |
| 2018 |    10 |   28 |
| 2018 |    11 |   05 |
| 2018 |    11 |   04 |
| 2018 |    11 |   03 |
| 2018 |    11 |   06 |
| 2018 |    11 |   07 |
| 2018 |    11 |   08 |
| 2018 |    11 |   09 |
+------+-------+------+
14 rows in set (0.00 sec)

mysql> insert into t1 values (2018,11,10);
Query OK, 1 row affected (0.02 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1;
+------+-------+------+
| year | month | day  |
+------+-------+------+
| 2000 |    01 |   01 |
| 2000 |    01 |   20 |
| 2000 |    01 |   30 |
| 2000 |    02 |   02 |
| 2000 |    02 |   23 |
| 2000 |    02 |   23 |
| 2018 |    10 |   28 |
| 2018 |    11 |   05 |
| 2018 |    11 |   04 |
| 2018 |    11 |   03 |
| 2018 |    11 |   06 |
| 2018 |    11 |   07 |
| 2018 |    11 |   08 |
| 2018 |    11 |   09 |
| 2018 |    11 |   10 |
+------+-------+------+
15 rows in set (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql>

-- session 2 ,在session 2 的事務中,看不到session1 中提交的資料。如果需要檢視到,則在查詢語句中增加for update ;

mysql> begin;
Query OK, 0 rows affected (0.00 sec)


mysql>
mysql> select * from t1;
+------+-------+------+
| year | month | day  |
+------+-------+------+
| 2000 |    01 |   01 |
| 2000 |    01 |   20 |
| 2000 |    01 |   30 |
| 2000 |    02 |   02 |
| 2000 |    02 |   23 |
| 2000 |    02 |   23 |
| 2018 |    10 |   28 |
| 2018 |    11 |   05 |
| 2018 |    11 |   04 |
| 2018 |    11 |   03 |
| 2018 |    11 |   06 |
| 2018 |    11 |   07 |
| 2018 |    11 |   08 |
| 2018 |    11 |   09 |
+------+-------+------+
14 rows in set (0.00 sec)

-- 增加for update ,可以看到新增加的資料了 。

mysql> mysql> select * from t1 for update;
+------+-------+------+
| year | month | day  |
+------+-------+------+
| 2000 |    01 |   01 |
| 2000 |    01 |   20 |
| 2000 |    01 |   30 |
| 2000 |    02 |   02 |
| 2000 |    02 |   23 |
| 2000 |    02 |   23 |
| 2018 |    10 |   28 |
| 2018 |    11 |   05 |
| 2018 |    11 |   04 |
| 2018 |    11 |   03 |
| 2018 |    11 |   06 |
| 2018 |    11 |   07 |
| 2018 |    11 |   08 |
| 2018 |    11 |   09 |
| 2018 |    11 |   10 |
+------+-------+------+
15 rows in set (0.00 sec)

mysql>

END