MS SQL表提示和锁定、并行性
情况如下: MS SQL 2008数据库,表大约每分钟更新一次。 表结构类似于以下内容:MS SQL表提示和锁定、并行性,sql,sql-server,database,transactions,parallel-processing,Sql,Sql Server,Database,Transactions,Parallel Processing,情况如下: MS SQL 2008数据库,表大约每分钟更新一次。 表结构类似于以下内容: [docID]、[warehouseID]、[docDate]、[docNum]、[partID]、[partQty] 典型工作循环: 用户从内部开发的系统开始数据交换: BEGIN TRANSACTION SELECT * FROM t1 WHERE [docDate] BETWEEN &DateStart AND &DateEnd AND [warehouseID] IN ('w1
[docID]、[warehouseID]、[docDate]、[docNum]、[partID]、[partQty]
典型工作循环:
用户从内部开发的系统开始数据交换:
BEGIN TRANSACTION
SELECT * FROM t1
WHERE [docDate] BETWEEN &DateStart AND &DateEnd
AND [warehouseID] IN ('w1','w2','w3')
…然后系统对所选数据执行相当长的处理,生成要从t1
中删除的[docID]s
列表,然后继续
DELETE FROM t1 WHERE [docID] IN ('d1','d2','d3',...,'dN')
COMMIT TRANSACTION
这里的问题是,当第一个事务处理选择数据时,另一个事务处理也读取数据,然后它们一起在内部系统中填充相同的数据
首先,我在SELECT查询中插入了(TABLOCKX)
表提示。在用户开始抱怨系统性能之前,它运行得相当好
然后我将提示更改为(ROWLOCK、XLOCK、HOLDLOCK)
,假设它会:
- 独占锁
- 所选行(而不是整个表)
- 直到交易结束
“选择…其中不包含[flag]”
)请告诉我 您可以更改工作流的概念 不删除记录,而是通过将额外字段
从0设置为1来更新记录
并不是从表中读取数据,而是从已弃用的视图中读取数据
BEGIN TRANSACTION
SELECT * FROM vT1
WHERE [docDate] BETWEEN &DateStart AND &DateEnd
AND [warehouseID] IN ('w1','w2','w3')
其中vT1
视图如下所示:
select *
from t1
where Deprecated = 0
UPDATE t1 SET Deprecated = 1 WHERE [docID] IN ('d1','d2','d3',...,'dN')
COMMIT TRANSACTION
删除将如下所示:
select *
from t1
where Deprecated = 0
UPDATE t1 SET Deprecated = 1 WHERE [docID] IN ('d1','d2','d3',...,'dN')
COMMIT TRANSACTION
使用这种概念,您将实现两个目标:
- 减少锁的概率
- 获取仓库的移动历史记录
此工作流如何帮助我们确保数据只处理一次?如果两个或多个用户同时启动exchange,目标系统将处理两组或多组相同的数据。这是一个新手问题,但视图是否可以仅针对单个用户显示?如果是,我们如何实现它?您可以将WITH(readpass)
提示添加到视图中:select*from t1 WITH(readpass),其中Deprecated=0
。在这种情况下,每个读取某些数据的用户都将等待该数据被更改。的确!感谢您提供如此简单而优雅的解决方案!