由于 2 个会话同时访问相同的存储过程,导致事务(进程 ID)死锁

Posted

技术标签:

【中文标题】由于 2 个会话同时访问相同的存储过程,导致事务(进程 ID)死锁【英文标题】:Transaction (Process ID) was deadlocked occurred due to accessing same stored procedure at same time by 2 sessions 【发布时间】:2018-02-28 12:04:15 【问题描述】:

当 2 个会话访问同一个存储过程时发生以下错误(由于 2 个用户/会话同时访问同一个存储过程而发生死锁)。错误:事务(进程 ID)在锁定资源上与另一个进程死锁,并已被选为死锁牺牲品。重新运行事务。

为删除基于where子句中日期过滤器的数据而编写的存储过程。 如何在这种情况下或任何替代方案中使用 SET DEADLOCK_PRIORITY。

【问题讨论】:

如何在这种情况下或任何替代方案中使用 SET DEADLOCK_PRIORITY。 重新设计您的程序以:1) 使用 updlock 提示 2) 使用 try...catch 处理死锁情况,在需要时重试 3) 在极端情况下使用 applocks 【参考方案1】:

当您使用共享资源进行线程处理时,您可以期待这样的行为。如果您需要更准确的答案,请提供更多信息。

当一个进程需要访问被另一个进程锁定的数据时,就会发生死锁。另一个进程想要访问第一个进程的数据,因此两者都无法继续。 SQL Server 足够聪明,可以识别出这种混乱并选择一个最喜欢的进程或停止这两个进程。

要解决此问题,如果可能,您最好不要设置 DEADLOCK 优先级。具有相同优先级的用户也可能导致死锁。最好的方法是在删除时同步访问。当其中一个删除过程在表上处于活动状态时,另一个应该等待。

这是这种同步的一个很好的例子: SQL Server - How to lock a table until a stored procedure finishes

【讨论】:

嗨 Georgi,等待进程是默认设置,否则我们必须设置任何参数。因为这里相同的存储过程被不同的victimProcess ID锁定。 这是一个更好的例子:***.com/questions/3662766/…. 您的目标是在删除过程中锁定整个表。当表被释放时,另一个存储过程将完成它的工作。关键是这样你将永远不会遇到死锁(因为一次只有一个过程可以锁定表行),尽管会损失一些效率。如果你设置了优先级,总会有另一个死锁的可能性。

以上是关于由于 2 个会话同时访问相同的存储过程,导致事务(进程 ID)死锁的主要内容,如果未能解决你的问题,请参考以下文章

mysql pdo 事务和会话存储

Sql Server并发和事务

oracle存储过程中临时表的使用,该怎么处理

这样的存储过程会导致死锁吗?

如何在pl / sql中同时在不同会话中执行存储过程

如何通过不提交当前会话事务将 DataTable 作为参数传递给存储过程?