在多个线程中执行 SQL 查询 (HSQLDB)

Posted

技术标签:

【中文标题】在多个线程中执行 SQL 查询 (HSQLDB)【英文标题】:Execute SQL Queries in multiple threads (HSQLDB) 【发布时间】:2014-05-15 08:26:29 【问题描述】:

假设我们有一个 SQL 数据库 (hsqldb),并希望在其上运行一些不修改内容的查询。 某些查询需要很长时间,我想在多个线程中运行查询。 所以我的问题是:实现这一点的最佳方法是什么?

我没有找到任何好的样品来做这个,所以我想出了以下(我很想买一些 cmets)。

首先,简单地说: 我使用线程安全的集合来访问查询并将结果放入其中。查询在多个工作线程中执行。结果在主线程中处理,主线程检查新结果,直到所有线程完成。

现在是代码:

创建查询和结果的线程安全集合:

ConcurrentLinkedQueue<String> queries = new ConcurrentLinkedQueue<String>()
ConcurrentLinkedQueue<ResultSet> sqlResults = new ConcurrentLinkedQueue<ResultSet>();

创建多个线程并启动它们(已编辑):

ExecutorService executorService = Executors.newFixedThreadPool(4);
for(int i=0; i<4; i++)
    executorService.execute(new QueryThread(sqlResults, queries));

在线程类 QueryThread 中打开一个连接,只要有剩余的查询就会执行:

private class QueryThread implements Runnable 
    private ConcurrentLinkedQueue<ResultSet> sqlResults;
    private ConcurrentLinkedQueue<String> queries;

    public QueryThread(ConcurrentLinkedQueue<ResultSet> sqlResults, ConcurrentLinkedQueue<String> queries)
        this.sqlResults = sqlResults;
        this.queries = queries;
    

    @Override
    public void run()
        Connection connThr = null;
        try
            try 
                connThr = DriverManager.getConnection(dbModeSave, "sa", "");
                connThr.setAutoCommit(false);
             catch (SQLException e1) 
                // TODO Auto-generated catch block
                e1.printStackTrace();
            

            String currentQuery;
            do 
                currentQuery = queries.poll(); // get and remove element from remaining queries
                if (currentQuery != null)  // only continue if element was found
                    try 
                        Statement stmnt = connThr.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
                        try 
                            ResultSet resultSet = stmnt.executeQuery(currentQuery);
                            sqlResults.add(resultSet);
                         catch (SQLException e) 
                            // (Do something specific)
                         finally 
                            stmnt.close();
                        
                     catch (SQLException e) 
                        // (Do something specific)
                    
                
             while (currentQuery != null);

         finally 
            if (connThr != null) 
                try 
                    connThr.close();
                 catch (SQLException e) 
                    // Nothing we can do?
                
            
        
    

从我检查的原始线程中,线程是否都已完成,因此所有查询都已处理(编辑)。

while (!executorService.isTerminated()) 
    try 
        Thread.sleep(100);
     catch (InterruptedException e) 
        Thread.currentThread().interrupt();
    
    while (!sqlResults.isEmpty()) 
        ResultSet result = sqlResults.poll();
        //process result and close it in the end
    

【问题讨论】:

【参考方案1】:

用于并行处理的 Java 标准解决方案是 ThreadPoolExecutor。试试看。

【讨论】:

好的,所以我把线程创建改为ThreadPoolExecutor。谢谢你。但我也感兴趣的是 ConcurrentLinkedQueue 和 SQL 操作的使用。

以上是关于在多个线程中执行 SQL 查询 (HSQLDB)的主要内容,如果未能解决你的问题,请参考以下文章

在 hsqldb 中调用 CHECKPOINT sql 是不是可以,而另一个 sql 可能正在进行中?

使用相同的语句对象在多个线程中执行多个查询?

HSQLDB:遇到重复的 sql 别名

立即执行 hsqldb

HSQLDB 删除触发器导致子查询出现问题

HSQLDB 内存设置的 HSQLDB 约束违规和 SQL 查询日志