`
xubaolin9
  • 浏览: 96162 次
社区版块
存档分类
最新评论

困扰我两年的Quartz的unscheduleJob和deleteJob问题

阅读更多

说来羞愧,这个问题困扰我2年时间,系统要通过UI设置定时任务,定时任务持久化到数据库,保证系统重启后定时任务仍可以执行,当然也需要随时取消定时任务,一旦取消任务,UI被锁住(其实是后台的处理程序被锁住了),需要3-5分钟才能恢复,一般情况下,后台会报数据库的错误。

 

问题出现后,我反复测试也没办法解决,反正锁住之后,一旦恢复,再操作,处理起来就很快了,先不管了。

 

去年新人要开发另外的系统,需要相同的组件,当然也就遇到了相同的问题,他也解决不了,因此他改用直接删数据的办法解决,但是工期紧,没太在意。现在我接手升级系统,发现问题依旧,还是绕不开这问题,没办法,按照正规的方法修正这个问题吧,要不不知要流毒多久

 

1.反复实验多次后,新人的做法无法解决问题,

2.重新改回用API的unscheduleJob和deleteJob处理,无效

3.怀疑是quartz的版本问题,原版本是1.6.0,下载了两个版本1.6.6,1.8.3,1.8.3版本太高,spring不认,换成1.6.6吧,问题依旧

4.没办法,修改log4j的配置文件,搞清quartz的原理再解决吧,日志如下

 写道
2010-07-22 13:37:40,796 (http-8888-Processor24) [ DBSemaphore.java:106:DEBUG] Lock 'TRIGGER_ACCESS' is desired by: http-8888-Processor24
2010-07-22 13:37:40,796 (http-8888-Processor24) [ DBSemaphore.java:106:DEBUG] Lock 'TRIGGER_ACCESS' is desired by: http-8888-Processor24
2010-07-22 13:37:40,796 (http-8888-Processor24) [StdRowLockSemaphore.java:89 :DEBUG] Lock 'TRIGGER_ACCESS' is being obtained: http-8888-Processor24
2010-07-22 13:37:40,796 (http-8888-Processor24) [StdRowLockSemaphore.java:89 :DEBUG] Lock 'TRIGGER_ACCESS' is being obtained: http-8888-Processor24
2010-07-22 13:37:40,796 (http-8888-Processor24) [ DBSemaphore.java:115:DEBUG] Lock 'TRIGGER_ACCESS' given to: http-8888-Processor24
2010-07-22 13:37:40,796 (http-8888-Processor24) [ DBSemaphore.java:115:DEBUG] Lock 'TRIGGER_ACCESS' given to: http-8888-Processor24
2010-07-22 13:37:40,828 (http-8888-Processor24) [ DBSemaphore.java:142:DEBUG] Lock 'TRIGGER_ACCESS' returned by: http-8888-Processor24
2010-07-22 13:37:40,828 (http-8888-Processor24) [ DBSemaphore.java:142:DEBUG] Lock 'TRIGGER_ACCESS' returned by: http-8888-Processor24
2010-07-22 13:37:53,406 (http-8888-Processor24) [ DBSemaphore.java:106:DEBUG] Lock 'TRIGGER_ACCESS' is desired by: http-8888-Processor24
2010-07-22 13:37:53,406 (http-8888-Processor24) [ DBSemaphore.java:106:DEBUG] Lock 'TRIGGER_ACCESS' is desired by: http-8888-Processor24
2010-07-22 13:37:53,406 (http-8888-Processor24) [StdRowLockSemaphore.java:89 :DEBUG] Lock 'TRIGGER_ACCESS' is being obtained: http-8888-Processor24
2010-07-22 13:37:53,406 (http-8888-Processor24) [StdRowLockSemaphore.java:89 :DEBUG] Lock 'TRIGGER_ACCESS' is being obtained: http-8888-Processor24
2010-07-22 13:37:53,406 (http-8888-Processor24) [ DBSemaphore.java:115:DEBUG] Lock 'TRIGGER_ACCESS' given to: http-8888-Processor24
2010-07-22 13:37:53,406 (http-8888-Processor24) [ DBSemaphore.java:115:DEBUG] Lock 'TRIGGER_ACCESS' given to: http-8888-Processor24
2010-07-22 13:37:53,421 (http-8888-Processor24) [ DBSemaphore.java:142:DEBUG] Lock 'TRIGGER_ACCESS' returned by: http-8888-Processor24
2010-07-22 13:37:53,421 (http-8888-Processor24) [ DBSemaphore.java:142:DEBUG] Lock 'TRIGGER_ACCESS' returned by: http-8888-Processor24
$$ unschedualResult = false
2010-07-22 13:37:53,421 (http-8888-Processor24) [ DBSemaphore.java:106:DEBUG] Lock 'TRIGGER_ACCESS' is desired by: http-8888-Processor24
2010-07-22 13:37:53,421 (http-8888-Processor24) [ DBSemaphore.java:106:DEBUG] Lock 'TRIGGER_ACCESS' is desired by: http-8888-Processor24
2010-07-22 13:37:53,421 (http-8888-Processor24) [StdRowLockSemaphore.java:89 :DEBUG] Lock 'TRIGGER_ACCESS' is being obtained: http-8888-Processor24
2010-07-22 13:37:53,421 (http-8888-Processor24) [StdRowLockSemaphore.java:89 :DEBUG] Lock 'TRIGGER_ACCESS' is being obtained: http-8888-Processor24
2010-07-22 13:37:53,421 (http-8888-Processor24) [ DBSemaphore.java:115:DEBUG] Lock 'TRIGGER_ACCESS' given to: http-8888-Processor24
2010-07-22 13:37:53,421 (http-8888-Processor24) [ DBSemaphore.java:115:DEBUG] Lock 'TRIGGER_ACCESS' given to: http-8888-Processor24
2010-07-22 13:38:07,796 (http-8888-Processor24) [ ExceptionHelper.java:97 :DEBUG] Detected JDK support for nested exceptions.
2010-07-22 13:38:07,796 (http-8888-Processor24) [ ExceptionHelper.java:97 :DEBUG] Detected JDK support for nested exceptions.
2010-07-22 13:38:07,796 (http-8888-Processor24) [ DBSemaphore.java:142:DEBUG] Lock 'TRIGGER_ACCESS' returned by: http-8888-Processor24
2010-07-22 13:38:07,796 (http-8888-Processor24) [ DBSemaphore.java:142:DEBUG] Lock 'TRIGGER_ACCESS' returned by: http-8888-Processor24
org.quartz.JobPersistenceException: Couldn't remove job: ORA-02292: 违反完整约束条件 (SYS_C0016583) - 已找到子记录
[See nested exception: java.sql.SQLException: ORA-02292: 违反完整约束条件 (SYS_C0016583) - 已找到子记录
]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.removeJob(JobStoreSupport.java:1313)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$6.execute(JobStoreSupport.java:1293)
at org.quartz.impl.jdbcjobstore.JobStoreCMT.executeInLock(JobStoreCMT.java:244)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.removeJob(JobStoreSupport.java:1289)
at org.quartz.core.QuartzScheduler.deleteJob(QuartzScheduler.java:835)
at org.quartz.impl.StdScheduler.deleteJob(StdScheduler.java:300)
 

记得源代码里有StdRowLockSemaphore,而且怪怪的,在系统的代码里面,检查quartz的代码,也有这个类,比较吧

package org.quartz.impl.jdbcjobstore;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Internal database based lock handler for providing thread/resource locking 
 * in order to protect resources from being altered by multiple threads at the 
 * same time.
 * 
 * @author jhouse
 */
public class StdRowLockSemaphore extends DBSemaphore {

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     * 
     * Constants.
     * 
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    public static final String SELECT_FOR_LOCK = "SELECT * FROM "
            + TABLE_PREFIX_SUBST + TABLE_LOCKS + " WHERE " + COL_LOCK_NAME
            + " = ? FOR UPDATE";

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     * 
     * Constructors.
     * 
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    /**
     * This constructor is for using the <code>StdRowLockSemaphore</code> as
     * a bean.
     */
    public StdRowLockSemaphore() {
        super(DEFAULT_TABLE_PREFIX, null, SELECT_FOR_LOCK);
    }
    
    public StdRowLockSemaphore(String tablePrefix, String selectWithLockSQL) {
        super(tablePrefix, selectWithLockSQL, SELECT_FOR_LOCK);
    }

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     * 
     * Interface.
     * 
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */

    /**
     * Execute the SQL select for update that will lock the proper database row.
     */
    protected void executeSQL(Connection conn, String lockName, String expandedSQL) throws LockException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
        	conn.setAutoCommit(false);
            ps = conn.prepareStatement(expandedSQL);
            ps.setString(1, lockName);
            
            if (getLog().isDebugEnabled()) {
                getLog().debug(
                    "Lock '" + lockName + "' is being obtained: " + 
                    Thread.currentThread().getName());
            }
            rs = ps.executeQuery();
            if (!rs.next()) {
                throw new SQLException(Util.rtp(
                    "No row exists in table " + TABLE_PREFIX_SUBST + 
                    TABLE_LOCKS + " for lock named: " + lockName, getTablePrefix()));
            }
            conn.commit();
        } catch (SQLException sqle) {
            //Exception src =
            // (Exception)getThreadLocksObtainer().get(lockName);
            //if(src != null)
            //  src.printStackTrace();
            //else
            //  System.err.println("--- ***************** NO OBTAINER!");

            if (getLog().isDebugEnabled()) {
                getLog().debug(
                    "Lock '" + lockName + "' was not obtained by: " + 
                    Thread.currentThread().getName());
            }
            
            throw new LockException("Failure obtaining db row lock: "
                    + sqle.getMessage(), sqle);
        } finally {
            if (rs != null) { 
                try {
                    rs.close();
                } catch (Exception ignore) {
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                } catch (Exception ignore) {
                }
            }
        }
    }

    protected String getSelectWithLockSQL() {
        return getSQL();
    }

    public void setSelectWithLockSQL(String selectWithLockSQL) {
        setSQL(selectWithLockSQL);
    }
}

 

发现我们的代码里面加入了这两行

conn.setAutoCommit(false);

conn.commit();

 

这代码是系统的创建者留下的,当时是基于什么考虑,也不可考了(代码里面没有注释)。他这么做肯定是欠妥的。

 

另外的问题,这么个问题延绵两年时间才搞定。。。

 

 

 

分享到:
评论
4 楼 xubaolin9 2010-11-18  
public void execute(JobExecutionContext ctx)


ctx里面你看看吧,应该是有的
3 楼 hhww0101 2010-11-10  
hhww0101 写道
我想问下楼主,知道定时任务执行时,如何取到任务的信心吗?比如triggerName 和 groupName

是信息,不是信心,打错字了!
2 楼 hhww0101 2010-11-10  
我想问下楼主,知道定时任务执行时,如何取到任务的信心吗?比如triggerName 和 groupName
1 楼 renwanly 2010-07-23  
conn.setAutoCommit(false); //关闭自动提交,目的是为了使用数据库事务提交;
conn.commit(); //提交数据库事务,如果其中出现任何异常则不会执行到这里;
conn.rollback(); //如果出现任何异常,可以回滚此事务;

相关推荐

    quartz job持久化

    实现把job持久化数据库,里面有具体的说明文档 Quartz 1 1 通过quartz创建持久化定时...1.3.1 实现org.quartz.Job接口 6 1.3.2 把以上job持久化到数据库中 6 1.4 启动job所需条件 6 1.4.1 在web.xml中加入如下监听 6

    quartz有状态Job和无状态Job

    在Quartz调度器中,根据Job是否能够保持状态,可以将其分为两类:有状态Job(Stateful Job)和无状态Job( Stateless Job)。这两种类型的Job在实现上有所不同,并且它们在应用场景中也各具特色。 #### 二、无状态Job ...

    quartz-1.6.0.jar和quartz-all-1.6.0.jar

    在给定的压缩包文件中,我们有两个版本为1.6.0的Quartz JAR包:`quartz-1.6.0.jar`和`quartz-all-1.6.0.jar`。这两个JAR包虽然名字相似,但它们的内涵有所不同。 `quartz-1.6.0.jar`是Quartz的基本库,包含了核心的...

    quartz动态添加、修改和删除定时任务

    Quartz是一款开源的作业调度框架,它允许开发者创建、安排和管理定时任务。在Java应用程序中,Quartz常被用来实现后台任务的自动化执行,比如数据同步、日志清理、发送邮件等。本教程将详细介绍如何动态地在Quartz中...

    quartz 调用两次任务

    2. **数据库存储问题**:Quartz 使用数据库存储 Job 和 Trigger 的信息,如果数据库中的记录不正确或被重复插入,可能导致任务被触发两次。 3. **集群环境下的并发问题**:在多服务器的集群环境中,如果未正确配置 ...

    spring java 定时器 执行两次 quartz

    总的来说,Spring集成Quartz提供了灵活的定时任务解决方案,但同时需要注意避免配置错误和并发问题,以防止任务被执行多次。通过理解Quartz的工作原理和Spring的定时任务API,我们可以有效地管理定时任务,确保它们...

    Quartz Job Scheduling Framework 中文版

    Quartz Job Scheduling Framework 是一个强大的、开源的Java作业调度框架,它允许应用程序定义和执行复杂的定时任务。这个框架的设计目标是提供一个简单且可扩展的解决方案,用于在分布式环境中调度作业。Quartz的...

    Quartz-JOB-Framework 中文版和QUartz开发指南 .zip

    在给定的压缩包文件中,我们有两个重要的资源:一个是"Quartz Job Scheduling Framework 中文版 V1.0.0 (1).chm",另一个是"Quartz开发指南.pdf"。 "Quartz Job Scheduling Framework 中文版 V1.0.0 (1).chm"是...

    Quartz调度、终止执行的任务

    Quartz是一款开源的作业调度框架,它允许开发者创建和安排任务执行。在Java应用程序中,Quartz能够帮助我们在特定的时间点或按照预设的周期执行某些功能,如数据收集、日志清理等。当我们需要终止某个正在运行的任务...

    quartz和spring-quartz

    Quartz和Spring-Quartz是两个在Java世界中广泛使用的定时任务管理框架。Quartz是一个开源的作业调度框架,允许应用程序定义和调度任务在特定时间执行。而Spring-Quartz则是Spring框架对Quartz的集成,它使得在Spring...

    quartz-job初始化数据表.zip

    Quartz 是一个开源的作业...总之,"quartz-job初始化数据表.zip" 文件是设置Quartz作业调度系统的关键步骤,它确保了数据库能正确地存储和管理所有的Job和Trigger信息,从而使得Quartz能够在适当的时间执行预定的任务。

    Quartz Job Scheduling Framework 中文版 V1.0.0.rar

    Quartz提供了多种类型的Trigger,如SimpleTrigger(简单触发器)、CronTrigger(基于Cron表达式的触发器)等,它们可以按照预设的时间间隔或特定的日期和时间触发Job。 3. **Scheduler(调度器)**:Scheduler是...

    Quartz Job Scheduling Framework 中文版 V0.9.2

    "Quartz Job Scheduling Framework 中文版 V0.9.2.chm"文件很可能是该框架的中文文档,包含了详细的API参考、使用示例和教程,对于学习和应用Quartz来说非常有价值。通过阅读这份文档,你可以深入理解Quartz的各个...

    Quartz_Job+Scheduling_Framework

    再次翻看一下我的博客,最早的那篇《 Quartz Job Scheduling Framwork 》翻译是在 2007 - 10 - 17 02:17 ,距离今日那是一个造人的时间,足见这个翻译过程有多难产。一方面是源于语言水平,再者其间也发生了许多事情...

    Quartz Job Scheduling Framework 中文版 chm版

    10. **最佳实践**:文档可能还会涵盖如何设计和配置Quartz以优化性能,以及避免常见问题的建议。 通过阅读这份中文版的Quartz文档,开发者可以深入理解Quartz的工作原理,掌握如何在项目中有效地利用它来安排和执行...

    关于spring中quartz的配置

    Spring提供的`SchedulerFactoryBean`允许在运行时动态地添加、修改和删除Job和Trigger,这样可以根据业务需求灵活调整定时任务。 通过以上步骤,你就可以在Spring中成功配置并使用Quartz进行任务调度了。注意,...

    Quartz Job 中文文档 CHM格式

    该CHM格式的文档是Quartz Job Scheduling Framework的中文版本,版本号为V0.9.5,为用户提供了详尽的指南和参考。 在Quartz Job中,核心概念包括Job、Trigger、Scheduler和Calendar。Job代表一个具体的工作任务,你...

    Quartz Job Scheduling Framwork中文文档

    1. **Job和Trigger**:在Quartz中,任务被称为Job,而调度的时间规则称为Trigger。Job是执行的实体,而Trigger定义了Job何时应该被执行。开发者可以自定义Job类,实现特定的业务逻辑,Trigger则可以根据cron表达式或...

    spring和quartz的定时器的启动和停止例子

    在IT行业中,Spring框架和Quartz是两个广泛用于任务调度的重要工具。Spring提供了一种集成Quartz的方式,使得我们可以方便地在Spring应用中管理和执行定时任务。本篇将深入探讨如何在Spring中启动和停止Quartz定时器...

Global site tag (gtag.js) - Google Analytics