我设置Quartz 2.1.0以集群模式在Websphere中运行,使用JobStoreTX,我启用了org.quartz.scheduler.jmx.export,这样我就可以通过JMX访问quartz scheduler。
问题是当我想通过JMX调用某些方法时,我对sql做了一些异常:
java.lang.Exception: Failure obtaining db row lock: Not in transaction.
at org.quartz.impl.jdbcjobstore.StdRowLockSemaphore.executeSQL(StdRowLockSemaphore.java:116)
at org.quartz.impl.jdbcjobstore.DBSemaphore.obtainLock(DBSemaphore.java:115)
at org.quartz.impl.jdbcjobstore.JobStoreCMT.executeInLock(JobStoreCMT.java:238)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.removeTrigger(JobStoreSupport.java:1410)
at org.quartz.core.QuartzScheduler.unscheduleJob(QuartzScheduler.java:1026)
at org.quartz.core.QuartzScheduler.deleteJob(QuartzScheduler.java:934)
at org.quartz.core.QuartzSchedulerMBeanImpl.deleteJob(QuartzSchedulerMBeanImpl.java:352)
似乎调度程序中的所有操作都需要包含在事务中,但是当通过JMX调用时,不存在任何事务。我该如何解决?
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceName">myApp</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
<prop key="org.quartz.jobStore.tablePrefix">q</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadCount">5</prop>
<prop key="org.quartz.threadPool.threadPriority">5</prop>
<prop key="org.quartz.scheduler.skipUpdateCheck">true</prop>
<prop key="org.quartz.scheduler.jmx.export">true</prop>
<prop key="org.quartz.scheduler.jmx.objectName">quartz:type=QuartzScheduler,name=JmxScheduler</prop>
</props>
</property>
更新:
我正在使用spring,因此JobStoreTX
被覆盖到LocalDataSourceJobStore
UPDATE2
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<jee:jndi-lookup id="dataSourceCron" jndi-name="jdbc/..." />
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey" value="applicationContext" />
<property name="dataSource" ref="dataSourceCron" />
<property name="transactionManager" ref="transactionManager" />
<property name="overwriteExistingJobs" value="true" />
<property name="autoStartup" value="true" />
<property name="triggers" ref="jobTriggers" />
<property name="jobDetails" ref="jobDetails" />
(properties)
</bean>
答案 0 :(得分:0)
Spring事务管理器在通过应用程序启动的作业范围内处于活动状态,但是当通过JMX对同一作业进行攻击时,它不会处于活动状态。
您如何通过JMX注册可以发布的作业,您可以发布代码吗?
最好的方法是使用JMX Spring集成工具,可以通过JMX注册Spring bean,请参阅文档here。有here一个如何在JMX中发布Spring bean的例子。
答案 1 :(得分:0)
由于Quartz Scheduler
是一个托管的spring bean,你可以使用spring declarative transaction management来识别Scheduler
“事务”。
使QuartzSchedulerMBeanImpl
“事务意识到”可能是一种更简洁的方法,但这有点棘手,因为它不是一个托管的spring bean。 (它创建了here)。通过注册&amp;自己暴露mbean,你可以使用spring的声明式事务管理来使其“知道事务”。另一种方法是使用AspectJ使mbean“知道事务”。