有时我需要获取唯一 ID 并将其与记录一起存储,但我无法使用标识列。因此,我有一个使用标签字段和整数提供唯一 ID 的表。当需要一个唯一的 ID 时,我调用一个存储过程并传入标签,它会吐出与其关联的下一个 ID。当然,在具有并发事务的环境中可靠这一点很重要。也就是说,存储过程不应该为给定的标签两次返回相同的值。我对事务隔离的有限理解导致我做了以下事情:
1) 将事务隔离级别设置为可序列化
2) 从 UniqueIdTable WHERE label = @inputLabel 中选择 id
3) 更新 UniqueIdTable SET id = id + 1 WHERE label = @inputLabel
4) 返回 2) 中检索到的 id
但这真的安全吗?即使使用可序列化的隔离,两个线程是否仍然可以同时执行步骤 2)?据我了解,最高隔离级别仅保证单个事务将执行而不会遇到幻像行或更改来自其他线程的数据。如果是这种情况,对 GetID 函数的两个同时调用可能会返回相同的值。
我对隔离级别有误解吗?我如何保证不会发生这种情况?
我还有一个问题需要解决。假设我有一个表,其中有一个字段,其中包含第二个表的外键。最初第一个表中的记录在第二个表中没有相应的记录,因此我在该字段中存储 NULL。现在在某个时候,用户运行一个操作,该操作将在第二个表中生成一条记录,并让第一个表链接到它。这始终是一对一的关系,因此如果两个用户同时尝试生成记录,则会创建一条记录并与之链接,而另一个用户会收到一条消息,指出该记录已存在。如何确保不会在并发环境中创建重复项?