2013-04-16 95 views
0

我有這個腳本的人量身定做的,我看着它,並發現了一些我不知道是安全的:MySQL的交易和併發插入

交易裏面有連續2個插入,在2層不同的表,都帶有自動遞增的主鍵。它們應該是相同的(從第一個插入生成的主鍵=從第二個插入生成的主鍵)。

不要問我爲什麼,這是劇本的製作過程。

我是新來的交易,我不能完全弄清楚這裏是否存在併發問題。我想到另一個線程在同時運行,並與鍵結束了的可能性正在生成類似:

Thread #1: Table_A ID: 3          Table_B ID: 4 
Thread #2:      Table_A ID: 4  Table_B ID: 3 

我敢肯定(今天我只準備交易相關的文檔第一時間)交易不能防止這種情況發生,但我只是想確定我是否正確。

謝謝!

+0

您可以通過啓動兩個控制檯會話並按照您認爲會產生問題的順序逐步在每個會話中輸入您的事務來測試您的理論。你甚至可以用不同的隔離級別來嘗試同樣的事情來查看是否有改變。 – didierc

+0

對:)這根本沒有跨過我的腦海。我忘了整個控制檯的方法。謝謝! – teomor

回答

0

您的場景絕對有可能。

如果主鍵都應該是相同的兩個表中,你可能會覆蓋AUTO_INCREMENT第二個表,並明確將值:

INSERT 
INTO a (id) 
VALUES (NULL) -- this inserts an auto incremented value 

INSERT 
INTO b (id) 
SELECT LAST_INSERT_ID() -- this inserts the last value inserted into a in this session 
+0

是的。我知道。謝謝。我只是想確保我有一個真正令人擔憂的理由,因爲製作劇本的人可能在整個應用程序中都做了好幾次:( – teomor

1

你需要把串行事務隔離兩個連接的水平,以避免您所描述的情況中,或者通過與每個連接上設置tx_isolation

SET @@tx_isolation = SERIALIZABLE; 

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; 

或通過與設置全局隔離級別:

SET @@global.tx_isolation = SERIALIZABLE; 

SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE; 

其通過任何隨後打開連接繼承。在那個級別上,如果另一個交易已經在進行中,交易將阻止任何查詢,即。一個事務已經在相同的表上發出了一個查詢(讀或寫)。

有關詳細信息,請參見the mysql documentation