Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从EJB计时器中删除大量行_Java_Sql_Jpa_Timer_Ejb - Fatal编程技术网

Java 从EJB计时器中删除大量行

Java 从EJB计时器中删除大量行,java,sql,jpa,timer,ejb,Java,Sql,Jpa,Timer,Ejb,我需要在EJB计时器中从表中删除数百万行。 问题是计时器的事务超时时间为90秒,因此我应该将工作划分为小部分 因为我不知道90秒内可以删除多少行,所以算法应该循环并一次删除几行,直到时间快到为止 问题是: 如何在JPA中优雅地限制要删除的行数? 对时间戳早于某个日期的所有行进行删除 我想可以找到最早的第1000行并删除timestamp中我们有类似要求的行,下面是我们如何解决它的。我使用的是EJB3.0 计时器在应用程序启动时启动。服务器启动或模块部署在ServletContextListene

我需要在EJB计时器中从表中删除数百万行。 问题是计时器的事务超时时间为90秒,因此我应该将工作划分为小部分

因为我不知道90秒内可以删除多少行,所以算法应该循环并一次删除几行,直到时间快到为止

问题是: 如何在JPA中优雅地限制要删除的行数? 对时间戳早于某个日期的所有行进行删除


我想可以找到最早的第1000行并删除timestamp中我们有类似要求的行,下面是我们如何解决它的。我使用的是EJB3.0

计时器在应用程序启动时启动。服务器启动或模块部署在ServletContextListener中。 当计时器启动时,它最多处理100行挂起的数据。然后需要对查询结果进行排序并限制行数。 如果有100行,计时器将下一次超时时间安排为0毫秒。当它启动时,事务被提交,计时器在新事务中再次触发。 如果少于100行,计时器将在90秒内安排下一次超时。
例如,如果有250行,计时器将按顺序触发三次。如果正好有100行要处理,则只有一个小问题,在这种情况下,计时器按顺序触发两次,但第二次触发实际上什么也不处理。但总而言之,它工作正常。

我们有一个类似的需求,下面是我们如何解决它的。我使用的是EJB3.0

计时器在应用程序启动时启动。服务器启动或模块部署在ServletContextListener中。 当计时器启动时,它最多处理100行挂起的数据。然后需要对查询结果进行排序并限制行数。 如果有100行,计时器将下一次超时时间安排为0毫秒。当它启动时,事务被提交,计时器在新事务中再次触发。 如果少于100行,计时器将在90秒内安排下一次超时。
例如,如果有250行,计时器将按顺序触发三次。如果正好有100行要处理,则只有一个小问题,在这种情况下,计时器按顺序触发两次,但第二次触发实际上什么也不处理。但总而言之,它工作正常。

我在SQL中使用的一个技巧是根据页面中的平均行数删除前1000行、前100行或前10000行,如下所示:

DELETE top 1000 WHERE timestamp <= @ExpirationDate

重复调用此函数,直到没有行被删除为止,请使用@rowcount进行检查,否则您的时间不足。这个技术可以在JPA中实现吗?

我在SQL中使用的一个技巧是根据页面中的平均行数删除前1000行、前100行或前10000行,如下所示:

DELETE top 1000 WHERE timestamp <= @ExpirationDate

重复调用此函数,直到没有行被删除为止,请使用@rowcount进行检查,否则您的时间不足。这项技术可以在JPA中实现吗?

通过获得符合清理条件的行的排序列表,并使用与SetMaxResultInt相同的setFirstResultint解决了这个问题。通过这种方式,我可以从最早的项目中获得大约maxCount步数的项目排序

Query expired = dm.createNamedQuery("getExpiredElements");
expired.setParameter("currentTime", getCurrentTime());
expired.setMaxResults(maxCount);
expired.setFirstResult(maxCount);
@SuppressWarnings("unchecked")
List<Item> expiredChunk = (List<Item>) expired.getResultList();
long lastChunkEndTime = expiredChunk.get(0).getEndTime();
Query query = em.createNamedQuery("deleteExpiredItems");
query.setParameter("currentTime", lastChunkEndTime);
int result = query.executeUpdate();
return result >= maxCount;

如果需要再次执行,该函数至少会返回true。

通过获取符合清理条件的行的排序列表并使用与setMaxResultInt相同的setFirstResultint,解决了该问题。通过这种方式,我可以从最早的项目中获得大约maxCount步数的项目排序

Query expired = dm.createNamedQuery("getExpiredElements");
expired.setParameter("currentTime", getCurrentTime());
expired.setMaxResults(maxCount);
expired.setFirstResult(maxCount);
@SuppressWarnings("unchecked")
List<Item> expiredChunk = (List<Item>) expired.getResultList();
long lastChunkEndTime = expiredChunk.get(0).getEndTime();
Query query = em.createNamedQuery("deleteExpiredItems");
query.setParameter("currentTime", lastChunkEndTime);
int result = query.executeUpdate();
return result >= maxCount;

如果应该再次执行该函数,则该函数至少会返回true。

您仍将面临现有解决方案的事务过期问题

诀窍是在单独的事务中执行每个块,如下面的pesudo代码所示

@Entity

@NamedQueries ( value = {
    @NamedQuery (
        name = pagedDeleteExpiredItems
        query=    DELETE FROM MyTable
            WHERE (<table key>) IN (
                SELECT <table key> FROM (
                SELECT ROWNUM AS row_num, <table key> FROM MyTable
                WHERE timestamp <= :currentTime
                )
                WHERE row_num < :pageSize
            )
    )
})

public class MyEntity {
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    int doPagedDeleteExpiredItems(Date currentTime, int pageSize) {
        Query query = em.createNamedQuery("pagedDeleteExpiredItems");
        query.setParameter("currentTime", currentTime);
        query.setParameter("pageSize", pageSize);
        int deleteCount = query.executeUpdate();
        return deleteCount;
    }
}


@EJBTimer
public class DeleteExpiredItemsTimer {

    @EJB(beanName = "MyEntity")
    MyEntity myEntity;

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    void handleTimeout(Timer timer) {
        Date currentTime = getCurrentTime()
        int pageSize = 100
        int deleteCount;
        do {
            myEntity.doPagedDeleteExpiredItems(currentTime, pageSize);
        } while(deleteCount>0);
    }
}

使用现有的解决方案,您仍将面临事务过期问题

诀窍是在单独的事务中执行每个块,如下面的pesudo代码所示

@Entity

@NamedQueries ( value = {
    @NamedQuery (
        name = pagedDeleteExpiredItems
        query=    DELETE FROM MyTable
            WHERE (<table key>) IN (
                SELECT <table key> FROM (
                SELECT ROWNUM AS row_num, <table key> FROM MyTable
                WHERE timestamp <= :currentTime
                )
                WHERE row_num < :pageSize
            )
    )
})

public class MyEntity {
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    int doPagedDeleteExpiredItems(Date currentTime, int pageSize) {
        Query query = em.createNamedQuery("pagedDeleteExpiredItems");
        query.setParameter("currentTime", currentTime);
        query.setParameter("pageSize", pageSize);
        int deleteCount = query.executeUpdate();
        return deleteCount;
    }
}


@EJBTimer
public class DeleteExpiredItemsTimer {

    @EJB(beanName = "MyEntity")
    MyEntity myEntity;

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    void handleTimeout(Timer timer) {
        Date currentTime = getCurrentTime()
        int pageSize = 100
        int deleteCount;
        do {
            myEntity.doPagedDeleteExpiredItems(currentTime, pageSize);
        } while(deleteCount>0);
    }
}

是的,这正是我想做的。但是我如何才能限制优雅地删除的行数呢?类似于按时间戳DESC limit 100从MyTable ORDER中删除。确切的SQL语法将取决于您使用的数据库。使用JDBC,您可以获得受删除影响的行数,并按照我所描述的进行操作。但是我如何才能限制优雅地删除的行数呢?类似于按时间戳DESC limit 100从MyTable ORDER中删除。确切的SQL语法将取决于您使用的数据库。使用JDBC,您可以获得受删除影响的行数,并按照我所描述的进行操作。但是你的解决方案很漂亮。好吧,交易在我的约束下为我解决了。但你的解决方案很漂亮。