Mysql

如何在 MySQL 中不鎖定表的情況下管理並發?

  • January 11, 2017

在我們的 php 應用程序中,我們有一個表格記錄在接待處收到的訂單。由於我們最多可以有 7 個代理/活動帳戶,如何管理訂單表中的並發而不必每次都鎖定表。

問題是:

  1. 在主表中插入任何行之前,必須對客戶進行一系列檢查,等等……這會強制進行多項選擇,然後是插入。
  2. 訂單由代理批量載入,而不是一個一個地載入。我擔心由於數據庫禁止訪問,鎖定表會迫使他們再次重做訂單的註冊。

我是否應該擔心 MySQL 的寫入管理,或者,我必須繼續使用鎖定係統?

並發和隔離是您在這里處理的兩個主題 - 多個使用者同時使用系統的能力以及每個使用者的工作不受其他使用者影響的能力。RDBMS 通過隔離級別和鎖來處理這個問題。這就是它們的設計方式;這就是他們所做的。作為應用程序架構師,我們的工作是選擇滿足要求的設置,並以最小化可能發生衝突的時間視窗的方式建構系統。

在此系統中,您希望 Order 表中的行與其他表中的行保持一致。為此,您需要鎖。這正是鎖的用途。不要害怕他們。他們是您的朋友並保護您的數據。對於引用表,您要確保僅通過讀取而不是寫入來獲取共享鎖,最好是行鎖。這樣多個並發活動可以共享參考數據。

編寫訂單將創建一個排他鎖。希望只是在新行上,但可能在桌子上。因此,通過在插入後儘快送出事務來快速釋放該鎖非常重要。

您不希望在代理鍵入時持有這些鎖。這在電腦術語中是永恆的。無論如何都要在輸入時驗證輸入,但只能作為單個語句,而不是在跨越整個數據輸入會話的事務中。然後在最後,當訂單被保存時,啟動一個事務,重新讀取引用數據,插入訂單並送出。在任何應該在毫秒內完成的平台上。其他操作員甚至不會注意到它的發生。如果出現錯誤或衝突,代理將立即獲得回饋,他們可以更正並重新送出。

有一個替代方案,我不推薦,但出於興趣在此列出。您可以在非同步消息處理設計上建構系統。當代理保存數據時,它會被寫入單個暫存表,每個數據值有一列。沒有驗證,沒有標準化。一次插入和數據的持久化。使用 7 個操作員,甚至一次在數據庫中進行兩個操作的可能性幾乎為零。第二個程序輪詢該表以一次讀取一行。它驗證並寫入規範化模式。結果——成功或失敗——被記錄下來。然後處理暫存表中的下一行,依此類推。這保證了所有插入都是完全序列化的,但代價是設計更加複雜,沒有立即回饋給代理,並且需要額外的業務流程和程式來糾正錯誤。這也不能防止來自連接到數據庫的其他程序的活動。畢竟必須有一些東西在閱讀這些訂單。正如我所說,不推薦。

七個代理同時輸入數據並不是一個大數字。我保證,你能夠建構一個系統來處理這個問題。

引用自:https://dba.stackexchange.com/questions/115192