2015-10-14 66 views
3

我的數據庫包含名爲sample_table表由名爲user_first_name一列和表是空並行事務

假設我有2個交易這樣

START TRANSACTION; 
INSERT INTO sample_table VALUES("TEJA"); 
INSERT INTO sample_table VALUES("TEJA"); 
INSERT INTO sample_table VALUES("TEJA"); 
INSERT INTO sample_table VALUES("TEJA"); 
INSERT INTO sample_table VALUES("TEJA"); 
INSERT INTO sample_table VALUES("TEJA"); 
INSERT INTO sample_table VALUES("TEJA"); 
//......... till 10000 times 
COMMIT 

START TRANSACTION; 
SELECT * FROM sample_table; 
SELECT * FROM sample_table; 
SELECT * FROM sample_table; 
SELECT * FROM sample_table; 
SELECT * FROM sample_table; 
SELECT * FROM sample_table; 
//........ till 10000 times 
COMMIT 

我並行運行這兩個交易以這種方式,首先transaction1開始,然後transaction1在transaction1運行時開始。我預計結果會有一些名爲TEJA的行。但我得到一個空的結果。 請幫我解釋爲什麼結果是空的?

回答

7

這一切都取決於您設置的ISOLATION LEVEL

可以看到哪一個你與此查詢設置:

select @@global.tx_isolation, @@session.tx_isolation; 

在解釋不同的隔離級別,讓我解釋一下,他們正試圖避免的問題:

  • 髒讀:另一個事務讀取尚未完成的事務的數據。

  • 丟失更新:兩個事務並行修改表中的一個條目。兩項交易完成後,只會應用一項修改。

  • 非重複讀取:重新讀取讀取會導致不同的結果。

  • 幻像讀取:在一個事務中,另一個事務添加,刪除或修改表項。

現在爲不同的隔離級別。

未提交讀
此隔離級別的讀操作忽略任何鎖,因此上面提到的任何可能出現的問題。

提交讀
此隔離級別設置爲對象上整個交易應該被修改的寫鎖。只有在讀取數據時纔會設置讀鎖。因此可能出現不可重複的讀取和幻像讀取。

重複讀
此隔離級別可以確保,即reoccuring讀操作總是產生相同的結果時的參數是相同的。對於事務的總持續時間,鎖被設置爲讀和寫操作。因此只能進行幻像讀取。

Serializable接口
最高的隔離級別保證,即平行運行的事務的結果是一樣的,如果交易將運行一個接一個。大多數數據庫並不真的一個接一個地運行這些事務,這會導致性能損失太大。因此可能發生一個事務被中止。 MySQL例如用MVCC(多版本併發控制)來實現這一點。谷歌它,如果你想知道更多。這個答案太多了。

總而言之這個表說明它還有:

    | Lost updates | Dirty Read | Non-Repeatable Read | Phantom Read 
--------------------------------------------------------------------------------- 
Read Uncommitted | possible  | possible | possible   | possible 
Read Committed | impossible | impossible | possible   | possible 
Repeatable Read | impossible | impossible | impossible   | possible 
Serializable  | impossible | impossible | impossible   | impossible 
  • 在這個manual entry是一些關於它的更多信息,以及如何設置隔離級別。