为什么我不能使用调度程序安排固定延迟任务

时间:2014-09-03 21:09:21

标签: java mysql scheduled-tasks executorservice

我想使用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;
}

这是我的测试代码,用于将记录插入到具有截止日期的数据库:

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);
    }

}

记录将插入到DB中。在到期时间之后,预计将通过上面给出的计划任务删除它。但是在指定的到期时间之后,当我查询数据库时,记录仍然存在并且不会被删除。所以似乎根本没有执行计划任务。这有什么问题?

1 个答案:

答案 0 :(得分:1)

汤加,

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

解决此问题的另一种方法是使用预定的程序调用。您可以做的是将上面描述的过程移植到MySQL的PL上,并让它每隔n秒运行一次。通过这样做,你将失去对代码的可见性,但它也是每n秒运行一次程序的另一种巧妙方式。这样做的好处是,如果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();

如果您有任何疑问,请与我们联系!