0

SPARQLクエリを使用してゴマリポジトリからトリプルを削除および挿入したいのですが、両方の操作を単一のトランザクションとして実行したいと思います。

  1. 消去
  2. 入れる

トランザクション中に例外がスローされると、ロールバックが実行されます...しかし、機能していないようです。問題は、挿入クエリ中に例外がスローされた場合、ロールバックは実行されますが、以前に削除されたトリプルは回復されないことです(なぜですか?)。

ここにいくつかのコードがあります:

リポジトリ接続をラップし、SPARQLクエリを作成するためのいくつかのメソッドを提供するOwlimConnectorというクラスがあります。このクラスのコンストラクターで、接続を設定し、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();
}

一方、以前のOwlimConnectorとUserGroupDAOというデータアクセスオブジェクトを使用するWebサービス「updateUserGroup」があります。

@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

解決策は私が思っていたよりもはるかに簡単です。これは、メーリングリストのOntotextADから受け取った回答です。

「RemoteRepositoryを使用しているため、各更新はup.execute()ですぐにリモートリポジトリに送信され、そこですぐに自動コミットされます。

あなたができることは、サービスの各削除/追加操作で準備して実行する代わりに、すべての個々の更新の収集を開始し(たとえば、StringBuilderに)、oc.commit()で更新の全リストを一度に準備して実行することです(例外がスローされた場合に備えて、ロールバックのリストをクリアするだけです)

更新リクエストには、複数の「INSERTDATA」または「DELETEDATA」の更新を含めることができます...」

そしてそれは動作します!ありがとうございました。

于 2012-09-21T09:13:44.407 に答える