Mysql 的事務隔離
阿新 • • 發佈:2018-11-16
測試環境: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