【问题标题】:Quartz.Net - DeadlockingQuartz.Net - 死锁
【发布时间】:2011-07-27 23:32:59
【问题描述】:

我正在开发一个调度程序,它每 30 秒检查一次数据库中调查表的任何更改。调查表包含 Name、WhenDue 等字段(为简单起见)。

这是我所做的一步一步 - 我实际上使用 Quartz Job,它设置为每 30 秒触发一次以添加更多作业。

  • 加载在上次提取日期/时间后修改的所有调查
  • Foreach 通过它们并添加新的或更新现有的作业/触发器

程序在我第一次启动时运行良好,它会获取所有调查等。

但是,如果我进行调查并更改某些内容,我的程序会获取更改但它会引发异常

Quartz.JobPersistenceException: Couldn't acquire next trigger: Couldn't retrieve trigger: Transaction (Process ID 59) was deadlocked on lock resources with another process and has been chosen as the deadlock victim.

这不知道为什么会发生这种情况。欢迎提出任何建议,我现在花了几个小时试图找到它。

【问题讨论】:

  • 另外,忘记添加了。据我所知,即使抛出异常,quartz.net 数据库也会使用新设置进行更新。
  • 我认为正在发生的事情是当我添加/更新触发器 Quartz.Net 正在尝试扫描要触发的新事物,但是我的进程正在添加新触发器,因此它锁定了数据库.有什么想法吗?

标签: c# scheduling deadlock quartz.net


【解决方案1】:

当您使用 ADO Job Store 时,我相信这是 Quartz.Net 的一个已知问题。有一些建议似乎可以缓解该问题,例如将 UpdateLockRowSemaphore 与 SQLServer 一起使用或将 adojobstore 移动到单独的数据库。

这里是讨论该问题的 google 群组邮件列表中的 threads

【讨论】:

    【解决方案2】:

    看起来这是一个 SQL 异常,Quartz 只是将它向上传递到堆栈。尝试使用 NOLOCK 选项选择您的数据:

    select dbo.Table.Column
    from dbo.Table with(NOLOCK)
    where dbo.Table.OtherColumn = @Param;
    

    Google 以获取有关 NOLOCK 的更多信息。您很可能需要重新设计数据库架构或使用 NOLOCK(不一定是坏事)。

    【讨论】:

    • 会不会是 Quartz 本身被锁定了。在我提取最新调查后,我没有进行任何交易。我已经设法通过运行sched.Stop(); 来停止调度程序,然后在完成添加/更新调查时运行sched.Start(); 来进行临时修复。虽然不是理想的修复。
    猜你喜欢
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 2014-06-08
    • 2013-11-30
    • 2013-12-25
    • 2015-01-29
    相关资源
    最近更新 更多