来自不同数据源和数据库的异步多重查询

时间:2013-04-26 10:02:01

标签: java grails asynchronous datasource multiple-databases

我无法找到合适的解决方案:

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

如果可以使用其他数据源(例如具有特定API的远程Web服务,而不是关系数据库),那就太棒了。

我使用Spring / Grail并需要java解决方案,但我很乐意接受任何建议。

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

1 个答案:

答案 0 :(得分:2)

这是基本的OO。您需要从您正在使用的机制 - 数据库查询或Web服务调用中抽象出您想要实现的内容 - 加载数据。

这样的设计通常会涉及一个界面,它定义了可以完成的任务的合同,然后是多个实现类,根据它们的实现来实现。

例如,您最终得到的界面如下所示:

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

然后您将拥有JdbcDataLoaderWebServiceDataLoader等实现。在您的情况下,您需要另一种类型的实现,它给出一个或多个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接口,以便你可以在测试过程中交换不同的实现或使用模拟。

相关问题