我有一个系统将批量查询写入事务(以保持一致性),每个事务可以是 30-100 个查询集。这些是在多个表上完成的
同时使用内部选择对同一张表进行读取查询 - SELECT FROM table1... IN (SELECT from table 2...)
为了清楚起见 - 有一个写入事务的写入线程(每个事务写入所有表)和许多读取线程。
我收到死锁错误。1.死锁会不会跟IN选择有关?2. 如何让读取查询只提供已提交的数据,而不必等待当前事务提交(这意味着它可以返回先前提交的数据) 3. 死锁是否可能是由于事务花费太长时间而导致的完全的?
谢谢!
如果有人可以帮助我理解为什么以下交易陷入僵局?我为每个表提供 2 个事务和索引:
交易1:
SELECT blockId, blockData, syncedToGeneration, itemId
FROM blocks
WHERE indexId=@indexId
and itemId IN (SELECT itemId
FROM KeywordReferences
WHERE indexId=@indexId
AND keywordRootId IN (360,4498,359,1229))
Run Code Online (Sandbox Code Playgroud)
交易2:
UPDATE blocks
SET blockData=@blockData,
syncedToGeneration=@syncedToGeneration
WHERE indexId=@indexId
AND blockId=@blockId
Run Code Online (Sandbox Code Playgroud)
(请注意,第一笔交易中的“IN”部分要长得多,包含大约 30 个值,为了便于阅读,我将其截断了)
blocks 表有以下索引:
- indexId->blockId (Clustered)
- indexId->itemId
indexId->itemId
keywordReferences 表具有以下索引:
- indexId_>keywordRootId (Clustered)
- indexId->keywordRootId->score
- indexId->itemId
- indexId->blockId
波纹管是死锁图xml输出:
<deadlock-list>
<deadlock victim="process5a274c8">
<process-list>
<process id="process5a274c8" taskpriority="0" logused="0" waitresource="PAGE: 5:1:91671" waittime="2709" ownerId="122348" transactionname="SELECT" lasttranstarted="2012-04-19T21:23:26.680" XDES="0xf382aca0" lockMode="S" schedulerid="4" kpid="10992" status="suspended" spid="69" sbid="0" …Run Code Online (Sandbox Code Playgroud)