2009-04-27 145 views
2

這是否會導致與MySQL(InnoDB的)的競爭條件:MySQL的競爭條件

  1. 開始交易。

  2. 嘗試獲取記錄。

  3. 如果記錄不存在,則返回。

  4. 如果記錄存在,請將其刪除並添加一條日誌條目,說明該條目已被刪除。

  5. 結束事務(提交/回滾)。

是否有可能爲另一個進程剛剛2B刪除步驟之前開始,檢測記錄的存在,然後有兩個過程輸入貨品刪除條目記錄到日誌?

我需要採取哪些預防措施?

謝謝。

+0

您是否看到這種行爲?或者這純粹是一個理論問題? – Joe 2009-04-27 21:12:16

+0

如果您在日誌表上有唯一的索引,那麼第二個線程將無法在其中添加重複的條目,並且第二個線程將被回滾。再次指出救援。 – 2013-01-14 06:45:19

回答

4

在步驟2中使用'select for update'。只有一個進程可以鎖定該行,從而避免您描述的情況。

+0

是的,這引發了一些人,但*技術上*刪除是一種更新。 – Powerlord 2009-04-27 21:01:54

+0

我正在使用防止這種情況的ORM。 所以你可以確認這是一個競爭條件? – user96747 2009-04-27 21:08:46

+0

我不得不說,是的,這是一個競爭條件。 – Powerlord 2009-04-27 21:13:20

0

是的,在閱讀完其它事務後,可能會檢查表。

更糟的是,由於事務的工作方式,即使在刪除該行之後,任何啓動的新事務都會看到該行,因爲您尚未提交刪除操作。

SELECT ... FOR UPDATE是防止它的一種方法。

LOCK TABLE tablename是另一個。

不幸的是,由於您使用的是ORM,我不能說它是否有能力做到這兩者之一。

1

我認爲,熟練程序員有正確的解決方案。既然你已經表明你正在使用一個破損的ORM工具(一個不允許你查詢更新的工具),我建議你將你的INSERT移入日誌表到刪除操作的觸發器中,這樣你就可以避免重複條目。

1

開始交易。

刪除記錄/使用您使用非常相同的標準*「試圖獲得創紀錄的」 */

如果響應表示記錄確實已被刪除,添加一個日誌條目。

結束事務(提交/回滾)。

沒有更多的競爭條件。