【问题标题】:Quartz.net clustered is throwing errorQuartz.net clustered 抛出错误
【发布时间】:2014-12-04 19:16:00
【问题描述】:

我正在尝试在集群环境中运行quartz.net(2 个使用单个数据库作为作业数据存储的石英服务)。我在quartz.exe.config 中设置了quartz.jobStore.clustered = true 和其他属性,如下所示

<quartz>
    <add key="quartz.jobStore.tablePrefix" value="Qrtz_"/>
    <add key="quartz.jobStore.misfireThreshold" value="60000"/>
    <add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"/>
    <add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz"/>
    <add key="quartz.jobStore.dataSource" value="myDS"/>
    <add key="quartz.dataSource.myDS.connectionString" value="Server=DEV1;user=dev2;password=P&ssW0rd;database=DATAU"/>
    <add key="quartz.jobStore.useProperties" value="false"/>

    <add key="quartz.dataSource.myDS.provider" value="SqlServer-20"/>
    <add key="quartz.scheduler.exporter.type" value="Quartz.Simpl.RemotingSchedulerExporter, Quartz"/>
    <add key="quartz.scheduler.exporter.port" value="555"/>
    <add key="quartz.scheduler.exporter.bindName" value="QuartzScheduler"/>
    <add key="quartz.scheduler.exporter.channelType" value="tcp"/>
    <add key="quartz.scheduler.exporter.channelName" value="httpQuartz"/>
    <add key="quartz.jobStore.clustered" value="true" />
</quartz>

但是,我收到以下错误

错误 Quartz.Impl.AdoJobStore.JobStoreTX - ClusterManager:管理集群时出错:获取数据库行锁失败:第 1 行:FOR UPDATE 子句仅允许用于 DECLARE CURSOR。

我正在使用 SQL2012(应用了最新的 Service Pack)作为作业存储。

此外,我尝试用以下属性替换锁定查询

<add key="quartz.jobStore.selectWithLockSQL" value="SELECT * FROM &#123;0&#125;LOCKS UPDLOCK WHERE LOCK_NAME = '?'" />

如果我这样做,我会收到以下错误

[QuartzScheduler_QuartzScheduler-NON_CLUSTERED_MisfireHandler] 错误 Quartz.Impl.AdoJobStore.JobStoreTX - MisfireHandler:错误处理失败:获取数据库行锁失败:违反主键约束“PK_QRTZ_LOCKS”。无法在对象“dbo.QRTZ_LOCKS”中插入重复键。重复键值为 (QuartzScheduler, TRIGGER_ACCESS)。

根据评论中的要求,这是我的完整工作配置

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
    <section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    <sectionGroup name="common">
        <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging"/>
    </sectionGroup>
</configSections>
<common>
    <logging>
        <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net1211">
            <arg key="configType" value="INLINE"/>
        </factoryAdapter>
    </logging>
</common>
<connectionStrings>
    <add name="EARTHEntities" connectionString="metadata=res://*/DatabaseModel.EarthModel.csdl|res://*/DatabaseModel.DBhModel.ssdl|res://*/DatabaseModel.DBModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=server;initial catalog=db;user=remoteuser;password=pwd;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient"/>
</connectionStrings>
<log4net>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %-6level %logger - %message %exception%newline"/>
        </layout>
    </appender>
    <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %-6level %logger - %message %exception%newline"/>
        </layout>
    </appender>
    <appender name="GeneralLog" type="log4net.Appender.RollingFileAppender">
        <file value="Quartz.log"/>
        <appendToFile value="true"/>
        <rollingStyle value="Date"/>
        <datePattern value="yyyyMMdd"/>
        <maxSizeRollBackups value="1"/>
        <maximumFileSize value="5MB"/>
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
        </layout>
    </appender>
    <root>
        <level value="INFO"/>
        <appender-ref ref="GeneralLog"/>
        <appender-ref ref="EventLogAppender"/>
        <appender-ref ref="ConsoleAppender"/>
    </root>

</log4net>
<!-- 
    We use quartz.config for this server, you can always use configuration section if you want to.
    Configuration section has precedence here.  
-->
<quartz>
    <add key="quartz.jobStore.tablePrefix" value="Qrtz_"/>
    <add key="quartz.jobStore.misfireThreshold" value="60000"/>
    <add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz"/>
    <add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz"/>
    <add key="quartz.jobStore.dataSource" value="myDS"/>
    <add key="quartz.dataSource.myDS.connectionString" value="Server=server;user=remoteuser;password=pwd;database=db"/>
    <add key="quartz.jobStore.useProperties" value="false"/>

    <add key="quartz.dataSource.myDS.provider" value="SqlServer-20"/>
    <add key="quartz.scheduler.exporter.type" value="Quartz.Simpl.RemotingSchedulerExporter, Quartz"/>
    <add key="quartz.scheduler.exporter.port" value="555"/>
    <add key="quartz.scheduler.exporter.bindName" value="QuartzScheduler"/>
    <add key="quartz.scheduler.exporter.channelType" value="tcp"/>
    <add key="quartz.scheduler.exporter.channelName" value="httpQuartz"/>
    <add key="quartz.jobStore.clustered" value="true" />
    <add key="quartz.jobStore.lockHandler.type" value="Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz"/>
    <add key="quartz.scheduler.instanceId" value="AUTO" />
</quartz>

【问题讨论】:

  • 您可以发布(附加到您的原始帖子).. 您的完整配置和工作配置吗?谢谢。
  • @granadaCoder 我已经做到了。

标签: quartz-scheduler quartz.net


【解决方案1】:

尝试使用此配置设置:

properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.MSSQLDelegate, Quartz";

等等,那个可能已经老了....

也许是这个:

    <add key="quartz.jobStore.lockHandler.type"
value="Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz"/>

从这个例子中找到:

https://groups.google.com/forum/#!topic/quartznet/Csw2un9KUy0

我从记忆中开始......我没有我曾经拥有的工作示例......

这里有一些代码可以帮助解决这个问题:

所以也许使用“Quartz.Impl.AdoJobStore.SqlServerDelegate”而不是“Quartz.Impl.AdoJobStore.StdAdoDelegate”是一种选择。

namespace Quartz.Impl.AdoJobStore
{
    /// <summary>
    /// A SQL Server specific driver delegate.
    /// </summary>
    /// <author>Marko Lahma</author>
    public class SqlServerDelegate : StdAdoDelegate
    {


namespace Quartz.Impl.AdoJobStore
{
    /// <summary>
    /// Provide thread/resource locking in order to protect
    /// resources from being altered by multiple threads at the same time using
    /// a db row update.
    /// </summary>
    /// <remarks>
    /// <para>
    /// <b>Note:</b> This Semaphore implementation is useful for databases that do
    /// not support row locking via "SELECT FOR UPDATE" or SQL Server's type syntax.
    /// </para>
    /// <para>
    /// As of Quartz.NET 2.0 version there is no need to use this implementation for 
    /// SQL Server databases.
    /// </para>
    /// </remarks>
    /// <author>Marko Lahma (.NET)</author>
    public class UpdateLockRowSemaphore : DBSemaphore
    {

【讨论】:

  • 使用SQLServerDelegate时不要添加quartz.jobStore.lockHandler.type,它会自动添加必要的优化配置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-28
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 2015-03-24
相关资源
最近更新 更多