2011-10-22 51 views
0

我有一個數據庫要求,這是您在大多數數據庫介紹中看到的標準開票系統的輕微改動。我的發票系統有多個不相關的「辦公室」。因此,各個發票號碼根據辦公室而不同。實際的發票號碼明顯不同於主鍵。在哪裏存儲另一個表格列的計數器?

例如,辦公室A和B都可以有不同的發票#1005。

是否有存儲另一個表的計數器的最佳做法?

create table Offices (
    Id integer primary key, 
    InvoiceCounter integer not null, 
    Name varchar(32) not null 
); 

create table Invoices (
    Id int primary key, 
    InvoiceNumber int not null, 
    Comment varchar(512) not null 
    -- other columns... 
); 

這是我想創建一個新的發票時的算法:

  1. 查看該辦公室目前InvoiceCounter。
  2. 遞增1並插入發票。
  3. 用新的InvoiceCounter號碼更新Office。

這是否有意義?

+1

是否在多個主管局重複使用#1005要求?爲什麼不直接將Office.Id放入Invoice表中並依賴Invoice表上的標識列? –

+0

@NathanSkerl - 我應該提到,每個辦公室的現有數據庫也有一個導入。發票顯然是打印的,因此如果客戶用#1005打電話打印發票,則A中對1005的引用必須完好。 – TheCloudlessSky

回答

0

自己需要關注的一件事就是競爭條件的可能性。例如。人們試圖獲得下一個發售#他們都得到1006回來。

要避免這一點sp_getapplock當你計算下一個號碼

之所以這樣,是一個好主意,因爲交易通常不會塊讀取阻攔。例如T1讀取1005,但在寫入1006之前,T2也讀取1005.當T1完成時,事務T2繼續並寫入1006.如果唯一密鑰正確,這將導致事務失敗。

+0

交易是否不能解決此問題? – TheCloudlessSky

+0

我更新了我的回覆。 –

0

我想你想盡量不要顯式阻止,如果你可以。只有這樣做纔是最後的手段。如果由於同一辦事處的兩次交易拉同一發票號而導致交易失敗,您是否可以重試交易?失敗的交易只需重新獲取給定辦公室的下一個可用發票號碼即可。

這確實假設你有一個唯一的密鑰,其中包含辦公室#和發票#。