2012-06-09 49 views
0

下一個獨特的價值我有我開發我的組織跟蹤工作訂單的MySQL數據庫(InnoDB的)。有多個「點」,並且每個站點都有工單號爲100。MySQL的獲得不帶自動增量

WorkorderID SiteID SiteWorkorderNum 
    1   1   100 
    2   1   101 
    3   2   100 

開始WorkorderID是自動遞增領域。
SITEIDSiteWorkorderNum都設置爲唯一約束。

每當一個新的工作秩序即將被插入一個特定的網站,爲最大(SiteWorkorderNum)的任何人所登錄的SITEID應用程序檢查和返回值的INSERT語句。我想避免的問題是,如果同一個網站的兩個用戶同時進入新的工作訂單。

我有幾個可能的解決方案,但我想看看是否有更好的方法,因爲每個都有缺點,但我肯定會比另一個更好,當然我也接受新的想法。

1)鎖表,以保證沒有其他用戶檢索SiteWorkorderNum值,直到經過我們檢索和插入我們的價值觀(但是讓我們假設我們有用戶試圖進入工單,每分鐘幾千,豈不如果我收到一個唯一的約束錯誤,捕獲錯誤並再試一次,請不要鎖定表,並檢索下一個可用的SiteWorkorderNum並嘗試插入到數據庫中直到我成功。 (這可能保持騰出表,但再次假裝我們在同一地點有成千上萬的用戶,將在多個數據庫調用有點低效?)

我是不是太偏執了有關如何這兩種解決方案「可能'效果表現?當然,我沒有成千上萬的用戶,但我想在這個設計的情況下,我曾經在一個項目裏面確實有高流量的工作應用的最佳實踐。

回答

0

一種選擇是使用交易。如果您將SELECT MAX(SiteWorkorderNum) ... WHERE SiteID=...與生成的插頁一起執行,那麼一切都應該起作用。唯一的問題是您的交易可能會失敗,這對用戶體驗可能不利。

我以前用過的另一個方案是有一個分配表SiteIdNextWorkorderNum列。只要做UPDATE SiteWorkorderAlloc SET @Num=NextWorkorderNum, NextWorkorderNum=NextWorkorderNum+1 WHERE SiteId=...。然後抓住@Num在隨後的插入中用作工單號。它工作正常,唯一的小缺點是,如果在獲取工單號和插入號之間發生崩潰,該工單號會丟失(從未使用過)。