我们有一个存储记录版本的表。
列是:
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。
有没有更好的方法可以让我使用可序列化的交易呢?
答案 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的事务隔离级别,但总体而言,最佳解决方案是使用约束。