死锁发生在1个单独的表上,其中2个用户执行简单的声明

时间:2017-06-19 21:16:17

标签: sql sql-server sql-server-2012 deadlock database-deadlocks

最终解决方案
我们实际上做的是通过创建一个工作表&而绕过逐行插入。会话ID,并且具有从临时表到主表的DELETE和INSERT的存储过程。没有更多的僵局! 最后的过程:

  • 从TheTable_work删除(使用sessionID,以防万一......)
  • INSERT INTO TheTable_work(与ADODB一行一行)
  • 我调用的存储过程执行以下操作:
    • BEGIN TRANSACTION
    • 从TheTable中删除(有些人 条件)
    • 从TheTable_work INSAT INTO TheTable(1 声明)
    • COMMIT
  • 从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试图了解原因
  • 我想明白为什么他们互相僵局而不只是“等待”直到另一个完成!我怎样才能做更好的操作? =)
  • 访问:它是带有SQL-Server后端的访问前端。没有链接表,vba代码通过ADODB连接推送查询。

编辑:死锁图
在左边我们有一个(3000)INSERT语句,在右边一个DELETE。 Deadlock graph

更新
我删除了DELETE语句中使用的列的索引,我再也无法重现死锁!不是一个干净的解决方案,但是暂时我们考虑临时表中的INSERT 3000行,然后一次从临时表复制到TheTable(存储过程中的DELETE和INSERT)。

谢谢,

SEB

1 个答案:

答案 0 :(得分:0)

DELETE将在页面上保留更新锁定:

  

更新(U)

     

用于可以更新的资​​源。 防止常见的形式   多个会话正在读取,锁定和发生时发生的死锁   可能会在以后更新资源。

INSERT将在同一页面上持有意图/排他锁。

  

独家(X)

     

用于数据修改操作,例如INSERT,UPDATE或   删除。 确保无法对其进行多次更新   资源同时。

     

意图

     

用于建立锁定层次结构。意图锁的类型是:   意图共享(IS), 意图独占(IX) ,并与意图共享   独家(SIX)。

如果您希望同时运行两个查询, 每个人都必须在给定的时间等待另一个人。

如果整套插入不需要回滚,建议您在单独的事务中运行每个插入。
或者,尝试删除并行化,或在不同时间执行这些操作。

简短:
1)在进入下一个INSERT之前,尽量确保每个INSERT都正确提交 2)或者尽量避免同时进行两种操作

另一个猜测是调整产生问题的会话的事务隔离级别。请查看以下文档。

参考:
Lock Modes
Transaction Isolation Level