【发布时间】:2017-11-22 05:34:22
【问题描述】:
最终解决方案
我们实际上所做的是通过创建一个工作表和会话 ID 来绕过逐行插入,并拥有一个存储过程,可以一次从临时表删除和插入到主表。没有更多的死锁!
最终流程:
- 从 TheTable_work 中删除(使用 sessionID,以防万一……)
- INSERT INTO TheTable_work(使用 ADODB 逐行)
- 我调用了一个存储过程:
- 开始交易
- 从 TheTable 中删除(带有一些 条件)
- 从 TheTable_work 插入到 TheTable (1 声明)
- 提交
- 从 TheTable_work 中删除(清理)
我们确实认为这是因为索引锁定,但我正在等待 DBA 的确认(解释 here)。
隔离级别没有任何改变(我们尝试了所有可能性,甚至打开和关闭 READ_COMMITTED_SNAPSHOT)
当 2 个用户同时“写入”数据库时,我的应用程序会导致数据库死锁。它们不适用于相同的数据,因为它们具有不同的 id,但它们适用于同一张表。
用户 1 (id = 1),用户 2 (id = 2)
流程
User 1 does : 1 DELETE statement, followed by 3000 INSERT
User 2 does : 1 DELETE statement, followed by 3000 INSERT
User 2 DELETE in the middle of user 1 INSERT (example : after 1500). Result in Deadlock.
声明(示例,但它们有效)
DELETE FROM dbo.TheTable WHERE id = 1 /* Delete about 3000 lines */
INSERT INTO dbo.TheTable (id, field2, field3) VALUE (1 , 'value2','value3')
我使用 ADODB (Microsoft Access...),所以我执行了一个简单的查询,例如:
ConnectSQLServer.Execute "DELETE or INSERT statement"
错误信息
Run-time error '-2147457259 (80004005)':
Transaction (Process ID76) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
其他信息
- 不涉及事务,只有简单的 INSERT 或 DELETE 查询, 一个一个
- 没有涉及 RecordSet,也没有打开
- 我们试图寻找死锁跟踪但没有显示图形,DBA 试图了解原因
- 我想了解他们为什么会互相僵持,而不是“等”到另一个完成!我怎样才能做更好的操作? =)
- Access : 它是一个带有 SQL-Server 后端的访问前端。没有链接表,vba 代码通过 ADODB 连接推送查询。
编辑:死锁图
左边有 1 个(共 3000 个)INSERT 语句,右边有一个 DELETE。
更新
我删除了 DELETE 语句中使用的列上的索引,我无法再重现死锁!不是一个干净的解决方案,而是暂时的。我们考虑在临时表中插入 3000 行,然后一次从临时表复制到 TheTable(在存储过程中删除和插入)。
谢谢,
塞伯
【问题讨论】:
-
“只有简单的INSERT或DELETE查询,一个一个”是什么意思?听起来您可能正在为此使用循环?但我也有点困惑。您的问题的 99.999% 显然是 sql server,但随后您提到了 Access。 Access是前端,所有的处理都在sql server吗?
-
如果你想了解死锁,你需要一个deadlock trace。没有两种方法。如果您有很多经验,可以对死锁是什么以及如何最好地解决它进行有根据的猜测,但即便如此,这也是危险的,因为您仍然很容易猜错。没有任何痕迹,我有根据的猜测是您的表有多个索引,
INSERT和DELETE将它们锁定在不同的、不兼容的顺序中,您通常通过战略性地增加锁定来解决这个问题。 但这是猜测。 -
您是否连接了 sql server 2012 并将访问用作链接表?
-
@SeanLange 和 M. Hassan : 抱歉访问混乱:它只是前端,没有链接表,我们使用 VBA 对 SQL-Server 进行 ADODB 查询。是的,有一个“循环”模式,因为用户输入内容并生成大约 3000 条 INSERT 语句,全部同时发送到数据库(一个接一个)。
标签: sql sql-server sql-server-2012 deadlock database-deadlocks