Connection to Sesame Store blocked
我在使用 SPARQL 查询sesame三联商店时遇到了问题。在我成功运行多个查询后,与三重存储的连接会阻塞。我已经能够在
我不明白为什么此时有 5 个打开的连接。
当我在
打开一个新连接
1 | connection = repository.getConnection(); |
我也关闭它:
1 2 3 4 5 6 7 8 9 10 11 | } finally { if(connection!=null){ try { connection.close(); nclosedconnections++; System.out.println("Connections:"+nconnections+" closed:"+nclosedconnections); } catch (RepositoryException e) { throw new SearchException("Could not close the triple store as a search engine.",this,null,e); } } } |
我已经检查了
每个连接也只使用一次(即用于一个 SPARQL 查询)。我也尝试过重用连接,但我仍然得到相同的块。
你有什么想法,为什么会出错,我该如何解决这个问题?
注意。 Sesame 存储库在 tomcat 上运行,并通过 HTTP 建立连接,即存储库是
1 2 | repository = new HTTPRepository(repositoryURL); repository.initialize(); |
我也查看了服务器上的sesame日志,但是sesame服务器没有收到请求。问题似乎出在没有发送请求的客户端。
NB2。以下是更完整的代码片段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | RepositoryConnection connection = null; String sparql ="" + "SELECT * WHERE {\ " + " OPTIONAL{ <"+result.getURI()+"> <" + DC.TITLE+"> ?title. }"+ " OPTIONAL{ <"+result.getURI()+"> <" + RDFS.LABEL+"> ?label. }"+ " OPTIONAL{ <"+result.getURI()+"> <" + SKOS.PREF_LABEL+"> ?prefLabel. }"+ " OPTIONAL{ <"+result.getURI()+"> <" + SKOS.ALT_LABEL+"> ?altLabel. }"+ " OPTIONAL{ <"+result.getURI()+"> <" + DC.DESCRIPTION+"> ?description. }"+ " OPTIONAL{ <"+result.getURI()+"> <" + RDFS.COMMENT+"> ?comment. }"+ "}\ "; try{ connection = repository.getConnection(); nconnections++; System.out.println("Connections:"+nconnections+" closed:"+nclosedconnections); TupleQuery query = connection.prepareTupleQuery(QueryLanguage.SPARQL,sparql); query.setMaxExecutionTime(2); TupleQueryResult results = query.evaluate(); while (results.hasNext()){ ... } } catch (RepositoryException e) { throw new SearchException("Could not access the triple store as a search engine.",this,null,e); } catch (QueryEvaluationException e) { throw new SearchException("Could retrieve data from the triple store as the SPARQL query could not be evaluated. SPARQL:\ "+sparql,this,null,e); } catch (MalformedQueryException e) { throw new SearchException("Could retrieve data from the triple store as the SPARQL query was malformed. SPARQL:\ "+sparql,this,null,e); } finally { if(connection!=null){ try { connection.close(); nclosedconnections++; System.out.println("Connections:"+nconnections+" closed:"+nclosedconnections); } catch (RepositoryException e) { throw new SearchException("Could not close the triple store as a search engine.",this,null,e); } } } |
发生这种情况的原因是您在完成后没有在
Sesame API 要求您在完成查询结果和迭代后显式调用
[...] it is important to invoke the close() operation on the TupleQueryResult, after we are done with it. A TupleQueryResult evaluates lazily and keeps resources (such as connections to the underlying database) open. Closing the TupleQueryResult frees up these resources. Do not forget that iterating over a result may cause exceptions! The best way to make sure no connections are kept open unnecessarily is to invoke close() in the finally clause.
推荐的模式是使用
1 2 3 4 5 6 7 8 9 | TupleQueryResult result = tupleQuery.evaluate(); try { while (result.hasNext()) { // process result items } } finally { result.close(); } |
顺便说一句,您在使用旧版本的 Sesame 时没有遇到此问题的原因是有一个未记录的功能,它会在查询结果完全耗尽时自动关闭它。
在 2.8 版中,完全重新实现了通过 HTTP 处理查询结果,这个未记录的特性不是其中的一部分。因此,虽然严格来说不是一个错误("官方"方式一直是您需要自己关闭它),但它是实际行为的回归。我已将此记录为问题(请参阅 SES-2323),它将在下一个补丁版本中修复。
顺便说一句,有几种方法可以使查询处理更容易一些,尤其是在您不需要对结果进行流式处理的情况下。例如,您可以执行以下操作:
1 | List<BindingSet> results = QueryResults.asList(query.evaluate()); |
将整个查询结果拉入一个简单的
此外:在即将发布的 Sesame 4.0 版本中(目前以 4.0.0-RC1 的形式提供),通过使用新的 Java 7/8 特性(例如