我有一个订单队列,由多个订单处理器通过存储过程访问.每个处理器都传入一个唯一的ID,用于锁定接下来的20个订单供自己使用.然后,存储过程将这些记录返回给订单处理器以进行操作.
在某些情况下,多个处理器能够检索相同的"OrderTable"记录,此时它们会尝试同时对其进行操作.这最终导致在该过程的后期抛出错误.
我的下一步行动是允许每个处理器获取所有可用的订单并且只是循环处理器,但我希望简单地使这部分代码线程安全,并允许处理器随时抓取记录.
所以明确地 - 任何想法为什么我遇到这种竞争条件以及如何解决问题.
BEGIN TRAN
UPDATE OrderTable WITH ( ROWLOCK )
SET ProcessorID = @PROCID
WHERE OrderID IN ( SELECT TOP ( 20 )
OrderID
FROM OrderTable WITH ( ROWLOCK )
WHERE ProcessorID = 0)
COMMIT TRAN
SELECT OrderID, ProcessorID, etc...
FROM OrderTable
WHERE ProcessorID = @PROCID
Run Code Online (Sandbox Code Playgroud) 我想使用数据库表作为队列.我想插入其中并以插入的顺序(FIFO)从中获取元素.我主要考虑的是性能,因为我每秒都有成千上万的这些交易.所以我想使用一个SQL查询,它给我第一个元素而不搜索整个表.我读的时候不会删除一行.SELECT TOP 1 .....帮忙吗?我应该使用任何特殊索引吗?
我有两个表TableA,TableB其中包含我想要检索和同时更新的信息.我用的时候
SELECT TOP 2 SomeFieldA
FROM TableA WITH (ROWLOCK , UPDLOCK , READPAST)
Run Code Online (Sandbox Code Playgroud)
一切正常,Process 1看到第1行和第2行,而Process 2看到第3行和第4行.这是预期的行为.此外,当我执行时,EXEC sp_lock我只看到两个KEY条目.但是,当我将语句更改为
SELECT TOP 2 SomeFieldA
FROM TableA WITH (ROWLOCK , UPDLOCK , READPAST)
INNER JOIN
Table B WITH ( ROWLOCK , UPDLOCK , READPAST )
ON TableA.ID = TableB.IDRef`
Run Code Online (Sandbox Code Playgroud)
第一个进程看到第1行和第2行,但进程2看不到任何内容.执行sp_lock显示现在所有行都被阻止.为什么会这样?
编辑:执行计划:
<?xml version="1.0" encoding="utf-16"?>
<ShowPlanXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="1.1" Build="10.50.1617.0" xmlns="http://schemas.microsoft.com/sqlserver/2004/07/showplan">
<BatchSequence>
<Batch>
<Statements>
<StmtSimple StatementCompId="2" StatementEstRows="2" StatementId="1" StatementOptmLevel="FULL" StatementOptmEarlyAbortReason="GoodEnoughPlanFound" StatementSubTreeCost="0.00670141" StatementText="SELECT TOP 2 …Run Code Online (Sandbox Code Playgroud)