0

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

  1. 删除
  2. 插入

如果在事务过程中抛出异常,则执行回滚......但它似乎不起作用。问题是,如果在插入查询过程中抛出异常,会执行回滚,但不会恢复之前删除的三元组(为什么?)。

这里有一些代码:

我有一个名为 OwlimConnector 的类,它包装存储库连接并提供一些方法来进行 SPARQL 查询。在此类的构造函数中,我设置了连接并将自动提交设置为 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 或空格时,MandatoryFieldException 异常被抛出并被 updateUserGroup 捕获。然后执行回滚,但删除的三元组不会恢复。

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

非常感谢您提前

4

1 回答 1

1

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

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

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

您的更新请求可以有多个“插入数据”或“删除数据”更新……”

它有效!谢谢你。

于 2012-09-21T09:13:44.407 回答