我想使用SPARQL查询从芝麻存储库中删除并插入三元组,并且希望将这两项操作作为一个事务执行。


删除



如果在事务期间抛出异常,则将执行回滚...,但似乎不起作用。
问题是,如果在插入查询期间抛出异常,则将执行回滚,但是先前删除的三元组将无法恢复(为什么?)。

这里有一些代码:

我有一个名为OwlimConnector的类,该类包装了存储库连接并提供了一些进行SPARQL查询的方法。
在此类的构造函数中,我建立了连接,并将autocommit设置为false:

RemoteRepositoryManager repos_manager = RemoteRepositoryManager.getInstance(SERVER_URL, USER, PASSWORD);
repos_manager.initialize();
Repository ssr = repos_manager.getRepository(REPOSITORY);
rconn = ssr.getConnection();
rconn.setAutoCommit(false);


在OwlimConnector中,有一个称为executeUpdate的方法:

public void executeUpdate(String queryString) throws RepositoryException,                MalformedQueryException, UpdateExecutionException
{
  Update up = rconn.prepareUpdate(QueryLanguage.SPARQL, queryPrefixString + queryString);
  up.execute();
}


以及以下方法:

public void commit(){
rconn.commit();
}

public void rollback() {
rconn.rollback();
}

public void close(){
rconn.close();
}


另一方面,我有一个Web服务“ updateUserGroup”,它使用以前的OwlimConnector和一个名为UserGroupDAO的数据访问对象:

@PUT
@Consumes(MediaType.APPLICATION_XML)
public Response updateUserGroup(UserGroup ug) {

try {
    oc = new OwlimConnector();
} catch (OwlimInstantiationException e) {
    return ResponseFactory.getError(e.getErrorMessage());
}

try {
    UserGroupDAO ugdao = new UserGroupDAO(oc);
    ugdao.delete(ug.getUri());
    ugdao.add(ug);
    oc.commit();
    oc.close();
    return ResponseFactory.getOK();
} catch (MandatoryFieldException e) {
    oc.rollback();
    oc.close();
    return ResponseFactory.getError(e.getErrorMessage());
} catch (NotExistingResourceException e) {
    oc.rollback();
    oc.close();
    return ResponseFactory.getError(e.getErrorMessage());
} catch (Exception e) {
    oc.rollback();
    oc.close();
    return ResponseFactory.getError(new GenericException(e).getErrorMessage());
}

}


1 ugdao.delete(ug.getUri())的作用是调用OwlimConnector方法executeUpdate:

oc.executeUpdate("DELETE { " + usergroup + " ?p ?v . } WHERE { " + usergroup + " ?p ?v . }");


即使没有提交,这里的三元组也会被删除!

2 ugdao.add(ug)的作用是:

要检查ug.getName()是否不是null或空格,否则将抛出MandatoryFieldException:

if (ug.getName() == null || ug.getName().equals("")){
throw new MandatoryFieldException("name");
}


然后,插入数据:

oc.executeUpdate("INSERT DATA { " + ug.getUri() + " a scmu:UserGroup ; scmu:hasName \"" + ug.getName() + "\" . }");


当ug.getName()为null或空格时,updateUserGroup引发并捕获MandatoryFieldException异常。然后执行回滚,但是删除的三元组无法恢复。

我不知道为什么会这样。任何的想法?

提前非常感谢你

最佳答案

解决方案比我想象的要容易得多。这是我从邮件列表中的Ontotext AD收到的答案:

“您正在使用RemoteRepository,因此每个更新都将立即通过up.execute()发送到远程存储库,并在此立即自动提交。

您可以做的是代替准备并在服务中的每个删除/添加操作上执行以开始收集所有单个更新(例如,收集到StringBuilder中),并在oc.commit()上立即准备并执行整个更新列表(并在回滚时清除列表,以防引发异常)

您的更新请求可以有多个“ INSERT DATA”或“ DELETE DATA”更新...”

而且有效!谢谢。

09-04 14:59