仅在附加表中设置版本列

时间:2010-01-03 11:17:43

标签: sql-server tsql

我们有一个存储记录版本的表。

列是:

Id (Guid)
VersionNumber (int)
Title (nvarchar)
Description (nvarchar)
etc...

保存项目会在表格中插入一个新行,并使用相同的Id和递增的VersionNumber。

我不确定如何生成顺序VersionNumber值。我最初的想法是:

SELECT @NewVersionNumber = MAX(VersionNumber) + 1
FROM VersionTable
WHERE Id = @ObjectId

然后在我的insert语句中使用@NewVersionNumber。

如果我使用此方法,是否需要将我的事务设置为可序列化以避免并发问题?我不想为同一个Id结束重复的VersionNumbers。

有没有更好的方法可以让我使用可序列化的交易呢?

2 个答案:

答案 0 :(得分:2)

为了避免并发问题(或者在特定情况下重复插入),您可以创建一个复合键作为表的主键,包括ID和VersionNumber列。然后,这将对键列强制执行唯一约束。

随后,您可以设计插入例程/逻辑来处理或更确切地说由于重复键而导致插入错误,然后只需重新发出插入过程。

值得一提的是,除非您特别需要使用GUID,即因为使用SQL Server Replication或多个数据源,否则您应该考虑使用其他数据类型,例如BIGINT。

答案 1 :(得分:2)

我原以为下面的单个插入语句会避免并发问题,但是在Heinzi对my question here的出色回答之后,结果证明这根本不安全:

Insert Into VersionTable
(Id, VersionNumber, Title, Description, ...)
Select @ObjectId, max(VersionNumber) + 1, @Title, @Description
From VersionTable
Where Id = @ObjectId

我要离开它仅供参考。当然,这可以使用表提示或Serializable的事务隔离级别,但总体而言,最佳解决方案是使用约束。