繁体   English   中英

数据库锁定问题

[英]Database Locking Problem

我们已经在生产数据库上获得了很多锁,最近见证了流量的大幅增加。 我们将IdeaBlade用于大多数数据访问。

我使用Sql Profiler得到了以下跟踪:

deadlock victim="process84af28"
  resource-list
    keylock hobtid="72057594096451584" dbid="6" objectname="cpc_db.dbo.Prefix_ChildTableName" indexname="PK_Prefix_ChildTableName" id="lock45982ac0" mode="X" associatedObjectId="72057594096451584"
      owner-list
owner id="processb852e8" mode="X" 
   owner-list
   waiter-list
    waiter id="process84af28" mode="S" requestType="wait" 
    waiter id="processb855b8" mode="RangeS-U" requestType="wait" 
   waiter-list
  keylock
  keylock hobtid="72057594096451584" dbid="6" objectname="cpc_db.dbo.Prefix_ChildTableName" indexname="PK_Prefix_ChildTableName" id="lock513c3bc0" mode="RangeS-U" associatedObjectId="72057594096451584"
   owner-list
    owner id="processb855b8" mode="RangeS-U" 
   owner-list
   waiter-list
    waiter id="processb852e8" mode="RangeS-U" requestType="wait" 
   waiter-list
  keylock
 resource-list
deadlock

有任何想法吗?

我不是DBA,但此跟踪似乎表明:

  1. 子表中的行上具有排他锁X的进程正在尝试获取同一资源上的Select-Update锁(似乎没有道理)

  2. 具有Select-Update锁定的另一个进程仍在尝试获取Select-Update锁定

澄清有人吗?

我们如何最小化或消除僵局?

首先要注意的几件事:

  1. 您正在使用可序列化事务 ,这是最严格的悲观锁定形式。 可能是不需要的(我们知道您正在使用可序列化的事务,因为KEY锁定仅适用于此隔离级别)。 正如Remus在上面提到的,您绝对应该在这里最有可能研究其他选项。

  2. 似乎上面的输出已被截断了一点,您应该有一个名为process-list的部分,其中包含将过程信息映射到spid和查询的信息

从上面的输出中您可以看出:

processb852e8 owns an exclusive lock on index "cpc_db.dbo.Prefix_ChildTableName.PK_Prefix_ChildTableName"
    process84af28 is waiting for a shared KEY lock
    processb855b8 is also waiting for a Shared Range-Update KEY lock

processb855b8 owns Shared Range-Update lock on index "cpc_db.dbo.Prefix_ChildTableName.PK_Prefix_ChildTableName" (the same index)
    processb852e8 is waiting on a Shared Range-Update KEY lock

排他锁是某种写操作(即更新,删除,插入),RangeS-U锁可能是更新,但是如果没有看到映射的信息就无法分辨。

Bart Duncan在掌握跟踪输出方面有很多不错的文章,请参阅第1 部分第2部分 您还可以在此处大致了解并发和脚本概述。

mode="RangeS-U"

范围锁? 停止使用较高的事务隔离级别。 坚持阅读提交。 如果使用CLR TransactionScope对象,则使它们使用Read Commited隔离(默认情况下,它们使用Seralizable,yuck)。 尝试打开数据库上的已读提交快照隔离。 请参阅使用快照隔离

罪魁祸首似乎是:

owner id="processb855b8" mode="RangeS-U"

这似乎已经锁定了一组行。 它的等待行由process84af28实现,它正在等待行由processb852e8实现,该进程正在等待第一个进程释放一行。

SQLServer通过杀死中间的进程以允许其他两个进程完成来解决死锁。

您应该查看隔离级别。 最佳实践是在“选择”多行时使用最低的可用锁定级别。 如果您很有可能在当前事务中更新该行,则仅在“选定”行上使用更高级别。

而且,永远不要在等待外部服务或用户操作时将行锁定。

我自己用其他产品(不是IdeaBlade)看到了这个死锁问题。 以我的经验,这不是数据库问题。 软件与数据库通信可能是一个问题。

我的问题是与数据库通信的组件的配置。

第一次,COM +默认为SERIALIZABLE,并且必须配置为默认为READ COMMITTED。

第二次,从COM +到.NET互操作的情况,导致数据库连接默认为SERIALIZABLE。

对于我们来说,一种快速而又肮脏的解决方案是在SQL命令之前加上“ SET TRANSACTION ISOLATION LEVEL READ COMMITTED”,以覆盖SERIALIZABLE,直到可以解决核心问题为止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM