0

我们有一个要求,当我们将一个新人加入数据库时​​,我们需要为他们分配一个唯一编号。当系统上线时,这个数字将从定义的数字开始。因此,如果客户说“从 500,000 开始!”,那么第一个分配的 ID 将是 500000。

容易 - 自动增加恶魔。

但是,这IDAccount Number发送给外部客户的,用于将该人链接到帐户。一个想法可能是使用 auto inc 主键,但我认为将 PK 用作面向外部的“人员编号”是很糟糕的。

有人提到有一个表,带有一个 auto inc pk,以及我们要添加数字的 person 表的 id。但这似乎很奇怪。

我的想法是在我们的表中添加一个新列settings,该列实际上只有一行,并且包含系统的系统设置。该列将是一个INT,并被称为NextAvailableId。这些行都有一Version列,即Timestamp( RowVersion)。

我的计划是创建一个名为GetNextId或其他东西的函数,它只需执行以下操作:

  1. 创建一个名为@AssignedID
  2. 创建一个名为@Version
  3. 从设置表中获取NextAvailableId,以及版本。
  4. Set AssignedID = NextAvailableId
  5. 更新设置表,设置NextAvailableId = AssignedID + 1 WHERE version = @Version
  6. 检查更新的行数。如果它是 1,那么我们设法在另一个进程获取 ID 之前获取最新的 ID,将其递增,并将其保存回表中。
  7. 如果更新的行数为零 - 那么有人在我们之前抓住了一个数字......所以,再试一次,直到我们有一个更新的行。

这听起来像是为我的人分配“帐号”的安全有效的计划吗?

请注意,它不是真正的人,也不是帐户代码。这是一个供应商 ID,需要应用于个人才能存储在单独的系统中。仅使用 Person 和 Account 作为(差)示例。

我需要做的是找到一种方法来处理“帐号”的唯一分配。如果手动方式是一个坏主意,并且有更好的方式 - 那么这将对我有很大帮助。

4

1 回答 1

2

虽然我不同意你手动增加最后一个 ID 的方法,但我同意 marc_s 需要注意并发性。

我将这样做的最快方法是将您的函数中的事务与READ UNCOMMITTED隔离级别和一个小的Mutex字段结合起来。这是伪代码:

  1. 使用 READ UNCOMMITED 开始新事务
  2. 检查是 Mutex 标志 = 0(没有其他方法运行)
  3. 如果标志 = 1,则循环
  4. 如果标志 = 0,则设置为 1
  5. 获取最后一个 ID
  6. 随心所欲地增加
  7. 在表中设置最后一个 ID
  8. 将 Mutex 标志设置回 0
  9. 返回新 ID / 提交事务

READ UNCOMMITED将允许多个执行检查 Mutex 标志的值,而其他事务仍在运行且尚未提交。

编辑 :

我建议您添加一个具有默认值的新列,而不是您的 PK。示例如下:

CREATE FUNCTION dbo.GetLastId()
RETURNS INT
AS
    BEGIN
        RETURN SELECT MAX(AccountID) + 1 FROM dbo.tblUsers
    END

-- Set the default value to the column
ALTER TABLE dbo.tblUsers
ADD AccountID SET DEFAULT (dbo.GetLastId())
于 2013-09-07T08:40:23.617 回答