2011-01-20 23 views
0

我有一張表,它類似於我想要訪問的URL列表。該表未被引用,也未引用其他表。 什麼我的應用程序做的是:如何鎖定一些行,因爲他們不會在其他交易中被選中

  • 從URL
  • 的列表中選擇一些行開始一個週期對他們
    • 開始transacion
    • 訪問URL
    • 闡述它
    • 開始一個子交易
      • 檢查結果是否已經在fi前兩個表(選擇)
      • 如果不是,將其保存(插入)
    • 提交子事務
    • 啓動子事務
      • 檢查結果是否已經在另一個表(選擇)
      • 如果不是,將其保存(插入)
    • 提交子事務
    • 更新我參觀
    • 行提交主要交易
  • 結束週期

有大量的錯誤檢查在這裏和那裏,主要交易有數百個查詢(選擇和插入),MySQL在CPU上非常高(我猜是因爲大的回滾日誌),但所有這些工作正常。

只有我不能運行這個批處理的多個實例,因爲它選擇的行大致相同:這意味着我在幾秒鐘內多次訪問一個URL,這是我不想要的。

如果我將主事務的開始移動到循環之外並選擇要更新的行,仍然沒有獲得多併發性,因爲第二個實例在第一個實例的主事務獲勝之前不會運行select不承諾。

一個可能的解決方案是添加一個「鎖定」字段到第一個表設置爲true(實際上到當前日期,因爲我試圖不使用布爾值)。

另一個是啓動主要事務,然後一次只選擇一行(更新)(設置「限制1」而不是5或10)。

我無法想像其他方式得到我想要的:不要選擇鎖定的行。

任何想法?

+0

*「我儘量不要使用布爾值」*。多麼奇怪。出於好奇,這是有原因的嗎? – LukeH 2011-01-20 16:29:45

+0

試圖不使用提供給你的工具阻礙了你的發展。你看到畫家拒絕滾筒嗎? – 2011-01-20 17:13:18

回答

1

聽起來好像您確實需要某種形式的標記來將行標識爲「正在使用」,以便其他實例不處理相同的數據;不管你使用布爾類型還是日期類型都無關緊要,你必須標記正在使用的行。

您既可以通過調度程序,進程或線程訪問您的表,也可以只選擇行並將其傳遞給其他進程以進行工作。即使這樣,調度員也必須知道他們得到的數據有多遠才能回到同樣的問題。

另一種方法是使用一個字段來指示行正在使用中(正如您在問題中所說的那樣)。每個進程用一個唯一的ID更新一個行塊,在一個事務中執行來鎖定表;我會使用從CONNECTION_ID()返回的連接號碼來標記它們,然後您知道它是唯一的。

UPDATE ... WHERE connection_id IS NULL(限制應用)事務處理完成後,進程可以SELECT ... WHERE connection_id = CONNECTION_ID()獲取它們的行進行處理。

當他們完成他們的工作後,整個週期再次開始標記下一組行,直到所有行都被處理完畢。

相關問題