【问题标题】:SQL Azure - Transaction (Process ID 160) was deadlocked on lock resources with another process and has been chosen as the deadlock victimSQL Azure - 事务(进程 ID 160)与另一个进程在锁定资源上死锁,并已被选为死锁牺牲品
【发布时间】:2016-12-20 13:49:24
【问题描述】:

我们在通过调用存储过程从并行线程对两个 SQL Server 表执行 CRUD 时遇到了提到的死锁异常,这里是详细的场景:

我们有一个桌面应用程序,我们在 100 到 150 个并行线程中启动一个代码块,代码块使用 SQL Bulk Copy 在 TableA 中插入并调用三个存储过程,存储过程执行插入、更新和根据 TableA 中的某些选择删除 TableB。

一旦应用程序开始执行线程,SQL Server 就会开始为一定数量的线程抛出上述死锁异常,而某些线程运行良好。

异常消息: 事务(进程 ID 160)与另一个进程在锁资源上死锁,并已被选为死锁牺牲品。重新运行事务。

提前感谢您提供这方面的任何帮助。

谢谢。

【问题讨论】:

    标签: sql-server multithreading transactions azure-sql-database


    【解决方案1】:

    这是 SQL Server 还是 SQL Azure/Azure SQL DB?如果它是“盒子”SQL Server,您可能会考虑 ALTER DATABASE SET READ_COMMITTED_SNAPSHOT ON。这将启用读取版本控制。在这种状态下仍然可能会遇到死锁,但它与你可能得到的银弹一样接近。

    读取版本控制以一些微妙的方式改变了并发模型,因此请务必先阅读它并确保它与您的业务逻辑兼容:https://msdn.microsoft.com/en-us/library/tcbchxcb(v=vs.110).aspx

    否则,Srivats 关于最小化事务范围的其他建议并不总是易于实现,但仍然是可靠的。在该列表中,我要添加:确保您有良好索引的查询访问路径,并验证您的事务中的所有查询都不需要全表或索引扫描。

    【讨论】:

    • 这是 SQL Azure 数据库。感谢您的指导,我们已经尝试了数据库级隔离和事务级隔离,似乎没有任何效果。
    • 启用快照隔离解决了我的问题。谢谢你! @KamalHaider 我的选择子句中也有“with (nolock)”,希望对您有所帮助!
    【解决方案2】:

    消息很明显,事务(进程 ID 160)在锁资源上与另一个进程死锁。锁可能位于不同的级别。在另一个线程可以锁定该特定资源之前,这些锁不会被释放。如果有任何锁定冲突,请尝试终止该进程 ID 并检查工作流。

    【讨论】:

    • 是的,因为是并行执行,访问同一个对象(两张表之一)会有冲突,但问题是我们如何避免死锁,使多个线程可以访问同一张表同时?数据库级别或存储过程级别是否有任何特定设置?
    • 以相同的顺序访问对象。保持交易简短,一批。使用较低的隔离级别。使用基于行版本控制的隔离级别。 ...使用绑定连接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多