C# Net-死锁

C# Net-死锁,c#,scheduling,deadlock,quartz.net,C#,Scheduling,Deadlock,Quartz.net,我正在开发一个调度器,它每30秒检查一次数据库,查看调查表中的任何更改。测量表包含诸如名称、WhenDue等字段(为简单起见) 这里是我一步一步做的-我实际上使用石英作业,设置为每30秒触发一次,以添加更多作业 加载上次提取日期/时间后修改的所有调查 Foreach,并添加新的或更新现有的作业/触发器 当我第一次启动这个程序时,它运行得很好,它得到了所有的调查结果等等 然而,若我进入调查并更改了某些内容,我的程序会在抛出异常的情况下拾取更改 Quartz.JobPersistenceExce

我正在开发一个调度器,它每30秒检查一次数据库,查看调查表中的任何更改。测量表包含诸如名称、WhenDue等字段(为简单起见)

这里是我一步一步做的-我实际上使用石英作业,设置为每30秒触发一次,以添加更多作业

  • 加载上次提取日期/时间后修改的所有调查
  • Foreach,并添加新的或更新现有的作业/触发器
当我第一次启动这个程序时,它运行得很好,它得到了所有的调查结果等等

然而,若我进入调查并更改了某些内容,我的程序会在抛出异常的情况下拾取更改

Quartz.JobPersistenceException:无法获取下一个触发器:无法检索触发器:事务(进程ID 59)在另一个进程的锁资源上被死锁,并被选为死锁牺牲品。


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

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

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

谷歌获取更多关于NOLOCK的信息。很可能您需要重新设计数据库模式或使用nolock(不一定是件坏事)。

我相信这是Quartz.Net在使用ADO作业存储时的一个已知问题。有一些建议似乎可以缓解这个问题,比如在SQLServer中使用UpdateLockRowSemaphore,或者将adojobstore移动到单独的数据库中


以下是谷歌集团邮件列表中讨论该问题的邮件。

还有,忘了添加。据我所知,即使引发异常,quartz.net数据库也会使用新设置进行更新。我认为发生的情况是,当我添加/更新触发器时,quartz.net正在尝试扫描要触发的新内容,但我的过程正在添加新触发器,因此它会锁定数据库。有什么想法吗?是石英本身锁住了。在我做了最新的调查后,我没有做任何交易。通过运行
sched.Stop(),我成功地完成了一个临时修复
停止调度程序,然后
sched.Start()当我完成添加/更新调查时。但这不是理想的解决方案。