我会尽力表达这个问题。给定这个基本对象和表模式:
文档
Name :: string
我的设计规范如下:
鉴于用户,
何时我创建了一个新的Document
,
和 Document.Name
不是唯一的,
然后追加" (N)"通过找到最高重复索引:到Document.Name
,并将n递增1。如果还没有重复项,则n初始化为2。
```
新文件
新文件(2)
新文件(3)
...
这看起来应该非常熟悉 - 类似于文件系统的行为方式。但是,我在处理此事务的可伸缩性方面遇到了问题。
POST文件
开始交易ReadCommitted
GetSimilarDocumentNames(即" {Document.Name}%")
ProcessNameForDuplication
插入文件
提交交易
退回文件
不幸的是,在并行请求下这不起作用,很明显我们需要某种锁定机制。
似乎我们需要将这种业务逻辑更深入地推入SQL并结合使用表锁。是否有其他可能的解决方案不需要这种限制性措施?
答案 0 :(得分:0)
如果您获得重复的数字,因为2个进程在同时调用#34; ProcessNameForDuplication"在它们都没有调用"插入文档"之前,有这样的表/功能应该有帮助
declare @DocNo int
begin tran
update
Document
set
@DocNo = DocNo,
DocNo = DocNo + 1
where
Name = @DocName
if (@@rowcount = 0) begin
insert into Document values (@DocName, 2)
set @DocNo = 1
end
commit
为了防止2个进程添加同一个文档,处理重复行错误的情况应该有所帮助,或者将隔离级别更改为SERIALIZABLE(https://msdn.microsoft.com/en-us/library/ms173763.aspx),这应该锁定表,直到添加文档为止。