Sql server 事务递增重复记录名称
我会尽力把这个问题说清楚。给定此基本对象和表架构: 文件 名称::字符串 我有一个设计规范,类似于: 给定用户,Sql server 事务递增重复记录名称,sql-server,transactions,Sql Server,Transactions,我会尽力把这个问题说清楚。给定此基本对象和表架构: 文件 名称::字符串 我有一个设计规范,类似于: 给定用户, 当我创建一个新的文档时, 并且Document.Name不是唯一的, 然后在文档中添加“(n)”。Name通过查找最高的重复索引:n,并将n增加1。如果不存在重复项,则n初始化为2。 ``` 例子 新文档 新文件(2) 新文件(3) 这看起来应该很熟悉-类似于文件系统的行为。但是,我在处理此事务的可伸缩性方面遇到了问题 控制流 邮寄文件 开始事务重新提交 GetSimilarDoc
当我创建一个新的
文档时,
并且Document.Name
不是唯一的,
然后在文档中添加“(n)”。Name
通过查找最高的重复索引:n,并将n增加1。如果不存在重复项,则n初始化为2。
```
例子
新文档
新文件(2)
新文件(3)
这看起来应该很熟悉-类似于文件系统的行为。但是,我在处理此事务的可伸缩性方面遇到了问题
控制流
邮寄文件
开始事务重新提交
GetSimilarDocumentNames(即“{Document.Name}%”)
ProcessNameForDuplication
插入文件
提交事务
返回文件
不幸的是,在并行请求下,这将不起作用,显然我们需要某种锁定机制
- 使用C#锁定无法跨多个web头工作
- 更改为ReadUncommitted不会有帮助,因为请求1必须在请求2查询类似文档名称之前完成Insert
似乎我们需要结合使用表锁,将此业务逻辑深入到SQL中。是否有其他可能的解决办法不需要这种限制性措施
如果使用了插入后触发器,我假设它们没有排队,而是立即运行,因此仍然必须发生某种锁定
如果由于两个进程在调用“Insert Document”之前调用“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
为了防止两个进程添加同一文档,处理重复的行错误情况应该有所帮助,或者将隔离级别更改为SERIALIZABLE(),这将锁定表,直到添加文档为止