我想实现 id 生成器,以便能够为多个表提供唯一的记录标识,并能够将 id 分配给在客户端形成的新记录的结构。
通常明显和标准的答案是 Guid,但由于空间效率和人类可读性,我想使用 int。
id 序列中存在间隙是可以的 - 这将发生在未完成的事务、丢失的客户端连接等情况下。
为了实现,我将有一个Counters
带有字段的表,NextId int
并在任何时候请求 id 时递增该计数器。当我需要多个或批量插入的 id 范围时,我可以将该 id 增加 1 以上。
为了避免更新Counters
表时出现锁定瓶颈,我需要使 id 请求原子化并且在任何其他事务之外。所以我的问题是如何做到这一点?
这在应用程序级别不是问题 - 它可以发出一个原子事务请求来获取 id 池,然后在另一个更大的事务中使用这些 id 来插入记录。
但是,如果我想在 Stored Procedure 或 Trigger 中获取新的 id,我该怎么办?
如果我将该update Counter set NextId=NextId+1
表请求包装到嵌套事务begin tran
中......commit tran
它不会将其排除在锁定之外,直到外部大事务结束。
有没有办法从当前事务中排除一个 Sql 语句,以便在语句结束时锁定结束,如果外部事务回滚,它不参与回滚。