在哪里存储另一个表的列的计数器?

时间:2011-10-22 16:41:03

标签: sql sql-server schema

我的数据库要求与您在大多数数据库介绍中看到的标准发票系统略有不同。我的发票系统有多个不相关的“办公室”。因此,每个办公室的相应发票号码不同。实际发票号明显不同于主键。

例如,办公室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. 获取Office的当前InvoiceCounter。
  2. 增加1并插入发票。
  3. 使用新的InvoiceCounter编号更新Office。
  4. 这有意义吗?

2 个答案:

答案 0 :(得分:0)

你需要关注的一件事是自那以后的竞争条件。例如。人们试图获得下一个Inv#,他们都得到了1006。

要避免这种情况,请在计算下一个数字时使用sp_getapplock来阻止

这是一个好主意的原因是因为事务通常不会阻止读取。例如T1读取1005但在写入1006之前,T2也读取1005.当T1完成时,事务T2继续并且写入1006.如果您的唯一密钥正确,这将导致您的事务失败。

答案 1 :(得分:0)

我想你想尽量不要明确阻止你。只做这个作为最后的手段。如果由于同一办公室拉动相同发票号码的两笔交易导致交易失败,您是否只能重试交易?失败的交易只需要重试获取给定办公室的下一个可用发票号。

这假设您有一个唯一的密钥,其中包含office#和invoice#。