问题1:在自由市场刷新时发现可能出现第一页球员填不满表格的情况,如下图:
这是因为我设置的自由球员过期事件处理,即从freemarketplayerlist中删除fpid的动作需要处理时间,而在这期间,有可能再对list进行查询,这时候会查到前10个fpid中的9个fpid已经过期,由于我在代码中进行了二次确认,如果发现fpid为null,那么就主动删除,导致原本查询10个球员,最后只返回了1个,这是原来的代码。
private List<FreeMarketPlayerDTO> getFreeMarketPlayerDTOPageListByListRange(Integer start,Integer end){
List<FreeMarketPlayerDTO> freeMarketPlayerDTOList=new ArrayList<>();
//得到当前自由市场的在给定区间的球员fpid
List<Object> freeMarketPlayerFpidList=redisTemplate.opsForList().range("freemarketplayerlist", start, end);
//遍历fpid,取出对应的freeMarketPlayerDTO的JSON字符串并转换为freeMarketPlayerDTO,将其加入list结果集
for(Object fpid:freeMarketPlayerFpidList){
String freeMarketPlayerDTOJSON= (String) redisTemplate.opsForValue().get("fp"+fpid);
//有可能找不到fpid,可能过期却还来不及从list中删除,因此这里再次进行确认和删除,由于到期的一定在左边,因此从左边删除
if(freeMarketPlayerDTOJSON==null){
redisTemplate.opsForList().remove("freemarketplayerlist", 1, fpid);
continue;
}
FreeMarketPlayerDTO freeMarketPlayerDTO=JSON.parseObject(freeMarketPlayerDTOJSON,FreeMarketPlayerDTO.class);
Long expireTime=redisTemplate.getExpire("fp"+fpid, TimeUnit.SECONDS);
//将过期时间(秒)转化为分:秒
freeMarketPlayerDTO.setTimeleft(DateTimeUtil.secondsToTime(expireTime));
freeMarketPlayerDTOList.add(freeMarketPlayerDTO);
}
return freeMarketPlayerDTOList;
}
要解决这个问题,不能一开始就取出固定数量的记录,而是要对记录进行计数判断,有效的记录数量等于10之后才能返回。
由于对list操作时间较慢,我将其改成index的形式来表示有效的球员数量
具体如下:
private List<FreeMarketPlayerDTO> getFreeMarketPlayerDTOPageListByRange(Integer start,Integer length){
List<FreeMarketPlayerDTO> freeMarketPlayerDTOList=new ArrayList<>();
int freeMarketPlayerTotalCount=getFreeMarketPlayerCount();
int freeMarketPlayerListCount=0;
//如果个数足够则必须取满length个非空自由球员
while(freeMarketPlayerListCount<length && start<=freeMarketPlayerTotalCount){
String freeMarketPlayerDTOJSON= (String) redisTemplate.opsForValue().get("fp"+start);
//如果是过期的,则继续取
if(freeMarketPlayerDTOJSON == null){
start++;
continue;
}
//如果不是空的,封装成FreeMarketPlayerDTO
FreeMarketPlayerDTO freeMarketPlayerDTO=JSON.parseObject(freeMarketPlayerDTOJSON,FreeMarketPlayerDTO.class);
Long expireTime=redisTemplate.getExpire("fp"+start, TimeUnit.SECONDS);
System.out.println(expireTime);
//将过期时间(秒)转化为分:秒
freeMarketPlayerDTO.setTimeleft(DateTimeUtil.secondsToTime(expireTime));
freeMarketPlayerDTOList.add(freeMarketPlayerDTO);
start++;
freeMarketPlayerListCount++;
}
return freeMarketPlayerDTOList;
}