我正在尝试在集群环境中运行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 {0}LOCKS UPDLOCK WHERE LOCK_NAME = '?'" />
如果我这样做,我会收到以下错误
[QuartzScheduler_QuartzScheduler-NON_CLUSTERED_MisfireHandler]错误Quartz.Impl.AdoJobStore.JobStoreTX - MisfireHandler:错误处理失误:获取数据库行锁定失败:违反PRIMARY KEY约束&#39; PK_QRTZ_LOCKS&#39;。无法在对象&#39; dbo.QRTZ_LOCKS&#39;中插入重复的密钥。重复键值为(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="data source=server;initial catalog=db;user=remoteuser;password=pwd;MultipleActiveResultSets=True;App=EntityFramework"" 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>
答案 0 :(得分:0)
尝试使用此配置设置:
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
{