来自不同数据源或数据库的异步多个查询



我很难找到合适的解决方案:

我有几个数据库具有相同的结构,但不同的数据。当我的web应用程序执行查询时,它必须为每个数据库分离此查询并异步执行,然后聚合所有数据库的结果并将其作为单个结果返回。此外,我希望能够传递查询将被执行的数据库列表,我还希望通过查询执行的最大过期时间。结果还必须包含每个数据库的元信息,如超额执行时间。

如果可以使用其他数据源,比如带有特定API的远程web服务,而不是关系数据库,那就太好了。

我使用Spring/Grail,需要java解决方案,但我很高兴得到任何建议。

UPD:我想找到准备好的解决方案,可能是框架或类似的东西

这是基本的OO。你需要从你正在使用的机制(数据库查询或web服务调用)中抽象出你想要实现的目标——加载数据。

这样的设计通常包括一个接口,该接口定义了可以做什么,然后多个实现类根据它们的实现来实现它。

例如,您最终得到的接口看起来像:

public interface DataLoader
{
    public Collection<Data> loadData() throws DataLoaderException;
}

你会有实现像JdbcDataLoader, WebServiceDataLoader等。在您的情况下,您将需要另一种类型的实现,给定一个或多个DataLoader实例,运行每个累积聚合结果。这个实现看起来像:

public class AggregatingDataLoader implements DataLoader
{
  private Collection<DataLoader> dataLoaders;
  private ExecutorService executorService;
  public AggregatingDataLoader(ExecutorService executorService, Collection<DataLoader> dataLoaders)
  {
    this.executorService = executorService;
    this.dataLoaders = dataLoaders;
  }
  public Collection<Data> loadData() throws DataLoaderException
  {
    Collection<DataLoaderCallable>> dataLoaderCallables = new ArrayList<DataLoaderCallable>>();
    for (DataLoader dataLoader : dataLoaders)
    {
      dataLoaderCallables.add(new DataLoaderCallable(dataLoader));  
    } 
    List<Future<Collection<Data>>> futures = executorService.invokeAll(dataLoaderCallables);
    Collection<Data> data = new ArrayList<Data>(); 
    for (Future<Collection<Data>> future : futures)
    {
       add.addAll(future.get());
    }      
    return data;
  }
  private class DataLoaderCallable implements Callable<Collection<Data>>
  {
    private DataLoader dataLoader;
    public DataLoaderCallable(DataLoader dataLoader)
    {
      this.dataLoader = dataLoader;  
    }
    public Collection<Data> call()
    {
      return dataLoader.load(); 
    }
  }
}

您需要在此添加一些超时和异常处理逻辑,但您已经了解了要点。

另一个重要的事情是您的调用代码应该只使用DataLoader接口,以便您可以在测试期间交换不同的实现或使用模拟。

最新更新