Mysql
MySQL master 到 master 競爭條件,我需要為這段程式碼使用事務/鎖嗎?
我正在使用 master 到 master MySQL 複製,希望我可以在兩個不同伺服器上的 C# 應用程序上執行兩個副本,以幫助提高性能。而不是我目前擁有的一台伺服器上的一份副本。
但是,我很難理解 MySQL 如何防止或處理競爭條件並維護數據庫的完整性。例如,我的應用程序具有類似於以下的程式碼。
SELECT 100 TASKS TO PROCESS UPDATE THE 100 TASKS TO SAY WE'RE WORKING ON THEM INSERT THE RESULTS OF THE 100 TASKS INTO THE DATABASE
因為上面的程式碼執行如此頻繁,最終我的應用程序將嘗試處理已被我的應用程序的另一個實例“選擇”但尚未“更新”的任務,當它這樣做時,它將嘗試“插入”數據已經插入,這會產生唯一的關鍵錯誤,從而破壞 MySQL 主控複製。
我可以從這個答案中看到 mysql 實例看起來非常獨立,並且似乎不知道彼此的鎖/事務。
我可以看到我可以使用下面的配置禁用唯一鍵錯誤,但我不確定這是否會導致比修復更多的問題。
slave-skip-errors=1169
這是我可以通過鎖和事務避免的嗎?
或者這只是主到主複製的一部分,我必須圍繞這個設計我的應用程序?
簡而言之 - 是的,您必須以一種能夠抵抗競爭條件的方式來設計您的應用程序。交易不會幫助你解決這個問題。
幾條評論…
- Master-Master 不會有太大幫助——對一個 master 的所有寫入都被“複製”到另一個 master。因此,您不會獲得太多的寫入縮放。
- 兩個客戶端(甚至 N 個客戶端)可以在一個主伺服器上競爭。但是這種爭用很容易通過事務處理。
- 一個人
UPDATE
可以原子地抓取 100 個任務。一條建議:
Loop: UPDATE Tasks SET who_has = $me WHERE ... -- if filtering needed ORDER BY ... -- if needed LIMIT 100; SELECT * FROM Tasks WHERE who_has = $me; process the tasks UPDATE Tasks SET who_has = NULL ... WHERE ... -- either all 100 or one at a time; end_loop.
如果“任務”可能相互干擾,則使用
BEGIN...COMMIT
. 但是讓我們討論一下它的細節。簡單INSERTs
的可以毫不費力地完成。