2014-09-03 78 views
0

我想使用Java的ScheduledExecutorService来计划延迟服务,以删除数据库中给定过期日期的某些行。但是我发现即使在指定的到期日期之后,数据库中的行也不会被删除。所以计划任务不会被执行。我的代码如下:为什么我无法使用调度程序安排固定延迟任务

public int addNewGroup(final String groupName, Category category, 
     Timestamp expireDate) { 

    String sqlQuery = "INSERT INTO Groups (name, category, expireDate) VALUES (?, ?, ?)"; 
    int numRows = jdbcTemplate.update(sqlQuery, new Object[] { groupName, 
      category.toString(), expireDate }); 

    //schedule the deleting temporary group task 
    if (category == Category.temp) { 
     final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); 
     Runnable task = new Runnable() { 
      @Override 
      public void run() { 
       String query = "DELETE FROM Groups WHERE name=?"; 
       jdbcTemplate.update(query, new Object[] {groupName}); 
      } 
     }; 
     scheduler.schedule(task, expireDate.getTime()-System.currentTimeMillis(), TimeUnit.MILLISECONDS); 
    } 
    return numRows; 
} 

这是我的测试代码中插入一条记录到有到期日的DB:

public class StoregroupDaoTest { 

    private StoregroupDao dao; 

    @Before 
    public void setup() { 
     ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 
     dao = context.getBean(StoregroupDao.class); 
    } 

    @Test 
    public void testAdd() { 
     String groupName = "ABC"; 
     Category category = Category.temp; 
     @SuppressWarnings("deprecation") 
     Timestamp expireTime = new Timestamp(114, 8, 3, 16, 57, 0, 0); //2014-09-03 16:57:00 
     int numRows = dao.addNewGroup(groupName, category, expireTime); 
    } 

} 

的记录插入到数据库。预计将在到期时间之后按照上面给出的计划任务进行删除。但是在指定的到期时间之后,当我查询数据库时,记录仍然存在,并且不会被删除。所以看起来计划任务根本就没有执行。这里有什么问题?

回答

1

汤加,

这使我的头脑,以确保ScheduledExecutor正确被调用和运行时,你希望它运行的第一件事情。我首先会尝试通过将DELETE语句更改为“INSERT”语句来确认这一点,如果需要,可将一些输出放入记录器。一旦你证实了这一点,我会尝试通过MySQL工作台和你所需要的参数来运行你的查询。一旦清除,我会尝试记录正在馈送到ScheduledExecuter的参数,并确保它们符合预期。一旦你验证了所有这些,你的查询应该按预期执行! :-)

解决此问题的另一种方法是使用预定的程序调用。你可以做的是将你上面描述的过程移植到你的MySQL的PL中,并让它每隔n秒运行一次。这样做会让代码的可见性下降,但这也是每隔n秒运行一次程序的又一种方式。这样做的好处是,如果ScheduledExecutor开始变得复杂,那么ScheduledExecutor可能会产生并发问题,而使用MySQL过程则更容易,更直接。

您可以使用mysql调度器每5秒运行一次。您可以在http://dev.mysql.com/doc/refman/5.1/en/create-event.html

发现样品可以在MySQL以如下方式安排一个存储过程:

CREATE EVENT myevent 
    ON SCHEDULE EVERY 5 SECOND 
    DO 
     delete_rows_links(); 

请让我知道如果您有任何问题!

+0

嗨Devarsh,谢谢你的建议。我在调度程序中放了一些日志打印输出,但它看起来并没有运行,因为在到期时间之前,根本没有打印输出。我也尝试在我的数据库中使用相同的DELETE查询,它工作正常。使用存储过程很好,但我真的想用Java代码来删除记录。我不知道为什么任务调度程序根本不运行。 – tonga 2014-09-03 21:28:43

+0

嘿汤加,是的!这通常是ScheduledExecuter的哈利部分 - 在你想要时运行:/你可以看看这些教程:http://www.java2s.com/Code/JavaAPI/java.util.concurrent/ScheduledExecutorServicescheduleRunnablecommandlongdelayTimeUnitunit.htm和http ://tutorials.jenkov.com/java-util-concurrent/scheduledexecutorservice.html;确保你的线程池大小足够大;请让我知道你做了什么进展,如果你有任何其他问题! :-) – 2014-09-03 21:36:43

+0

我还打印出调度程序的fed参数:'expireDate.getTime()'。毫无疑问,从时代开始毫无疑问。所以真的是一个难题。 – tonga 2014-09-03 21:43:46

相关问题