2017-09-16 183 views
-1

我正在運行多線程應用程序,並且遇到問題,而不同線程嘗試訪問特定表中的相同記錄。MySQL選擇更新並插入

線程A - 想因此,從表「LastOperations」最後一個記錄做了選擇用於更新ORDER BY ID DESC LIMIT 1 - 創建基於在LastOpertaions表的最後一條記錄的新紀錄,並插入回到它。

線程B - 想最後一個記錄表「LastOperations」,因此不

兩個線程都被相同的代碼相同的活動主題A.。只是使用不同的數據。此表上的最大活動線程數爲4-6。

問題 如果線程A鎖定最後一條記錄,並且標識號爲1000,則線程B將取999條記錄並向表中添加新條目。 ID字段是一個自動增量,它也是主鍵。

說線程1正在購買原材料A而線程b正在購買原材料B.兩者都應該通過採用最新條目從同一個賬戶中扣除。發生什麼事情是一個線程從帳戶進入較舊的帳戶,導致帳戶餘額錯誤。

關於我失蹤的任何建議?數據庫端需要進行哪些更改?

+0

真正的問題似乎是,你自己生成的ID。讓數據庫爲你做這件事 –

+0

從你的問題來看你想要做什麼並不明確。這兩個線程是否真的在做同樣的事情?您指出線程B執行與線程A相同的活動。 – jhenderson2099

+0

ID由數據庫自動遞增。 – kris123456

回答

0

我相信你遇到的問題是Transaction Isolation Level。線程A沒有創建它的記錄。因此,當線程B從「LastOperations」獲取最近的記錄爲999時,999確實是表中的最後一條記錄。

您可以將事務隔離級別更改爲READ UNCOMMITTED(如果您擁有對MySQL實例的控制權),但這是有風險的。如果您允許髒讀,那麼線程A生成的完整記錄可能無法在數據庫中完成。 (因此,「髒讀」中的'髒')。

+0

在DB端完成。仍然面臨問題。 – kris123456

+0

同意髒讀部分。帳戶主要是每個人都需要的表...這已成爲失敗點 – kris123456

+0

當前db使用讀取已提交。 – kris123456

0

不要混合歷史和當前。有兩個表格:

  • History列出所有動作;它大部分是INSERTed
  • Current列出了當前的餘額。它主要是UPDATEd

當一個動作發生:

BEGIN; 
SELECT ... FROM Current ... FOR UPDATE; 
INSERT INTO History ...; 
UPDATE Current ...; 
COMMIT;