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會話事務結束,再次查詢記錄才會變化