如何在不修改query.default-max-results的情况下删除Infinispan缓存中所有符合查询条件的条目?
问题描述
尝试通过以下代码删除大量符合条件的条目:
var query = "delete from package.Entity where field = :value"; var count = cache.query(query) .setParameter("value", value) //.maxResults(total) --> throws org.infinispan.commons.CacheException: ISPN014057: DELETE statements cannot use paging (firstResult/maxResults) .executeStatement();
但每次最多只能删除100条条目,原因是query.default-max-results默认值为100。尝试为查询设置maxResults为待删除总数时,会抛出CacheException(DELETE语句不允许使用分页参数)。修改缓存的query.default-max-results为更大值(如200)可以删除对应数量的条目,但不想修改这个全局配置,请问如何在不修改该配置的前提下删除所有符合条件的条目?
解决方案
可以通过以下两种方式实现:
方式一:循环执行DELETE语句直到删除数为0
利用默认的query.default-max-results限制,循环执行DELETE操作,直到某次执行返回的删除条数为0,说明所有符合条件的条目已删除完毕。示例代码:
long deleted; do { var query = "delete from package.Entity where field = :value"; deleted = cache.query(query) .setParameter("value", value) .executeStatement(); } while (deleted > 0);
这种方式无需修改全局配置,每次删除默认上限的条目,直到全部删完。
方式二:先查询所有符合条件的键,再批量删除
先通过查询获取所有符合条件的实体键,再调用缓存的批量删除方法一次性删除。示例代码:
// 查询所有符合条件的键 var keyQuery = "select e.id from package.Entity e where field = :value"; List<Object> keys = cache.query(keyQuery) .setParameter("value", value) .maxResults(Integer.MAX_VALUE) .list(); // 批量删除 if (!keys.isEmpty()) { cache.removeAll(keys); }
如果符合条件的条目数量极大,一次性查询所有键可能导致内存问题,此时可以分页查询键,再分批次删除:
int batchSize = 100; // 可根据实际情况调整 int offset = 0; List<Object> keys; do { var keyQuery = "select e.id from package.Entity e where field = :value"; keys = cache.query(keyQuery) .setParameter("value", value) .firstResult(offset) .maxResults(batchSize) .list(); if (!keys.isEmpty()) { cache.removeAll(keys); offset += batchSize; } } while (!keys.isEmpty());
内容的提问来源于stack exchange,提问作者Rafael Rocha
相关产品推荐
相关产品推荐

