程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> Mysql事務隔離級別

Mysql事務隔離級別

編輯:MySQL綜合教程

Mysql事務隔離級別


scott@PROD>select * from dept1;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        50 OPERATIONS     BOSTON
        20 DBA            Bei Jing
scott@PROD>update dept1 set deptno=21 where dname='DBA';

1 row updated.

scott@PROD>SELECT s.sid, s.serial#,
  2     CASE BITAND(t.flag, POWER(2, 28))
  3        WHEN 0 THEN 'READ COMMITTED'
  4        ELSE 'SERIALIZABLE'
  5     END AS isolation_level
  6  FROM v$transaction t 
  7  JOIN v$session s ON t.addr = s.taddr
  8  AND s.sid = sys_context('USERENV', 'SID');

       SID    SERIAL# ISOLATION_LEVE
---------- ---------- --------------
        41       5973 READ COMMITTED

Oracle數據庫支持READ COMMITTED 和 SERIALIZABLE這兩種事務隔離級別。
而Mysql支持READ UNCOMMITED,READ COMMITED,REPEATABLE READ,SERIALIZABLE四種事務隔離級別

READ UNCOMMITTED(讀取未提交內容)
在read uncommitted隔離級別,所有事物都可以”看到”未提交事物的執行結果。也就是髒讀(讀取未提交事務)

READ COMMITED (讀取提交內容)
ORACLE的默認隔離級別。一個事物開始時,只能”看見”已經提交事務所做的改變,一個事務從開始提交前,所做的任何數據改變都是不可見的,除非已經提交。這種隔離級別也就是不可重復讀

REPEATABLE READ (可重讀)
repeatable read隔離級別解決了read uncommitted隔離級導致的問題。它確保同一事務的做個實例在並發讀取數據時,會”看到”同樣的數據行。不過理論上,這會導致另一個棘手的問題:幻讀。簡單來說,幻讀指當用戶讀取某一范圍的數據行時,另一個事務又在該范圍內插入了薪行,當用戶再讀取該范圍的數據行時,會發現有新的”還原”行。

SERIALIZABLE (可串行化)
serializable是最高級別的隔離級,它通過強制事務排序,使之不可能相互沖突,從而解決幻讀問題。

Mysql默認的隔離級別是:

(mysql@localhost) [fandb]> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
session A:
(mysql@localhost) [fandb]> begin;
Query OK, 0 rows affected (0.00 sec)

(mysql@localhost) [fandb]> update per1 set name='fan1' where id=1
    -> ;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

(mysql@localhost) [fandb]> select * from per1 limit 1;
+----+------+
| id | name |
+----+------+
|  1 | fan1 |
+----+------+
1 row in set (0.00 sec)
A會話更新一行
session B:
(mysql@localhost) [fandb]> begin;
Query OK, 0 rows affected (0.00 sec)

(mysql@localhost) [fandb]> select * from per1 limit 1;
+----+------+
| id | name |
+----+------+
|  1 | fan  |
+----+------+
1 row in set (0.00 sec)
此時在B開始事務並查詢,id=1的name列並沒有變化
session A:
(mysql@localhost) [fandb]> commit;
Query OK, 0 rows affected (0.00 sec)
接著A會話提交
session B:
(mysql@localhost) [fandb]> select * from per1 limit 1;
+----+------+
| id | name |
+----+------+
|  1 | fan  |
+----+------+
1 row in set (0.00 sec)
在去B會話查詢,還是沒有變化
(mysql@localhost) [fandb]> commit;
Query OK, 0 rows affected (0.00 sec)

(mysql@localhost) [fandb]> select * from per1 limit 1;
+----+------+
| id | name |
+----+------+
|  1 | fan1 |
+----+------+
1 row in set (0.00 sec)
只有當B會話事務結束,再次查詢記錄才會變化

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved