Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 我怎样才能摆脱这种僵局?_Sql Server_Deadlock - Fatal编程技术网

Sql server 我怎样才能摆脱这种僵局?

Sql server 我怎样才能摆脱这种僵局?,sql-server,deadlock,Sql Server,Deadlock,我有两个查询涉及死锁情况,显示在下面的死锁图中。(Seitensperre表示页面锁定) 进程55中的查询是死锁受害者。它是一个select,包括订单和付款表 流程95上的查询中有几个查询 在开始时,ist做了一些选择,将一些值存储到变量中(访问表顺序) 然后更新表顺序,并在该表付款之后更新 我不明白这种情况怎么会导致僵局。你能解释一下僵局的原因吗?我能做些什么?我想我只是很难读懂死锁图 以下是所涉及的资源 <resource-list> <objectlock lock

我有两个查询涉及死锁情况,显示在下面的死锁图中。(Seitensperre表示页面锁定)

进程55中的查询是死锁受害者。它是一个select,包括订单和付款表

流程95上的查询中有几个查询 在开始时,ist做了一些选择,将一些值存储到变量中(访问表顺序) 然后更新表顺序,并在该表付款之后更新

我不明白这种情况怎么会导致僵局。你能解释一下僵局的原因吗?我能做些什么?我想我只是很难读懂死锁图

以下是所涉及的资源

<resource-list>
   <objectlock lockPartition="0" objid="1104059019" subresource="FULL" dbid="9" objectname="mycompany.dbo.order" id="lock1b9596980" mode="S" associatedObjectId="1104059019">
    <owner-list>
     <owner id="process443bac8" mode="S"/>
    </owner-list>
    <waiter-list>
     <waiter id="process20fc5eda8" mode="IX" requestType="wait"/>
    </waiter-list>
   </objectlock>
   <pagelock fileid="1" pageid="1825971" dbid="9" objectname="mycompany.dbo.Payment" id="lock1bca33000" mode="IX" associatedObjectId="72057594063159296">
    <owner-list>
     <owner id="process20fc5eda8" mode="IX"/>
    </owner-list>
    <waiter-list>
     <waiter id="process443bac8" mode="S" requestType="wait"/>
    </waiter-list>
   </pagelock>
  </resource-list>
以下是选择查询(流程55)


如果你能发布每个过程中涉及的声明,这将是很有帮助的,但这里是

如果
SELECT
语句正在进行聚合,则它们可以获取表锁。如果您的用例允许,您可以尝试使用带有(NOLOCK)提示的

UPDATE
语句实际上取决于被修改记录的范围——
WHERE
条件的选择性以及它是否有效地使用索引

如果涉及的表有任何触发器,那么您也需要仔细检查这些代码。根据我的经验,它们是造成僵局的最常见原因。特别是当发布的声明表面上看起来相对简单时。如果确实找到了触发器,请尝试禁用它们并在测试环境中运行这两条语句,以验证它们是否导致了死锁


然而,最终,僵局并不是总能避免的。您最好尽可能地优化,但始终要处理一条或两条语句被选为牺牲品的情况,并优雅地清理/现有语句,或重试批处理。

最后发现,这是调用代码的问题。这很难解释,但基本上是一笔交易被打开并交给了几个方法

我取消了交易,僵局消失了


当然,我必须再次重新实现事务,看看事务处理的实现方式是否真的有问题,或者事务的跨度是否太长

SELECT @id_orderAddress = id_orderAddress FROM order
 WHERE [id] = @id_order
对以下内容:

SELECT @id_orderAddress = id_orderAddress FROM order WITH(UPDLOCK)
 WHERE [id] = @id_order

这可确保同一“订单”行的后续更新不会导致死锁-“订单”行在事务开始时已被锁定。

您如何调用此过程?我没有看到任何“BEGIN TRAN”语句,因此我想知道您是否在SqlTransaction上下文中执行此操作。是的,updateOrderDetails是在通过ADO.NET打开的事务上下文中调用的。嗯。。。那就玩吧。我想,我知道密码…:)
SELECT @id_orderAddress = id_orderAddress FROM order
 WHERE [id] = @id_order
SELECT @id_orderAddress = id_orderAddress FROM order WITH(UPDLOCK)
 WHERE [id] = @id_order