3

私はグラフデータベースを始めたばかりで、学ぶのに最適なのはneo4jだと考えました。アプリケーション内で実行されているneo4jの埋め込みインスタンスがあります(JSFベース)。このアプリケーションの使用例は、主に、グラフ データベースの使用に関する概念と落とし穴を学び、最適な方法 (つまり、組み込みまたはスタンドアロン) を決定するのに役立ちます。しかし、私のテスト アプリケーションは、関係 (つまり、KNOWS、WORKS_WITH、WORKS_FOR など) を定義する機能を備えた非常に基本的な連絡先アプリであり、最終的にそれらの関係に基づいて推奨 (つまり、「あなたも知っているかもしれません」) を行うことができます。

これまでのところ、基本的なcrud操作があり、関係を追加/削除できます. 私の次のステップは、実際にグラフのトラバースを開始することです (私はそう思います)。しかし、私が現在実行している問題は、サーバーとのセッションが期限切れになると、ストアが現在使用されていることを訴える IllegalStateException エラーを取得せずに新しいセッションを再確立できないことです。これは、neo4j インスタンスで shutdown を呼び出したことがないためだと思います。したがって、これは私がトランザクションを処理する方法がすべて間違っていると考えるようになるので、誰かが私の理解 (場合によっては誤解) を修正してくれることを願っています。

Web クライアントと neo4j の間の操作を処理するために使用されているヘルパー クラスのいくつかのメソッドを次に示します。

public class NeoNodeUtils {
private GraphDatabaseService graphDb;

public NeoNodeUtils() {
    setup();
}

public void setup() {
    GraphDatabaseFactory neoFactory = new GraphDatabaseFactory();
    setGraphDb(neoFactory.newEmbeddedDatabase("Morpheus"));
    registerShutdownHook();
}

public GraphDatabaseService getGraphDb() {
    return graphDb;
}

public void setGraphDb(GraphDatabaseService graphDb) {
    this.graphDb = graphDb;
}

public Node getNode(Long id) {
    Transaction tx = getGraphDb().beginTx();
    Node node = null;
    try {
        node = getGraphDb().getNodeById(id);
        tx.success();
    } catch (Exception e) {
        tx.failure();
        e.printStackTrace();
    } finally {
        tx.finish();
        return node;
    }
}

public Node createNode() {
    Transaction tx = getGraphDb().beginTx();
    Node node = null;
    try {
        node = graphDb.createNode();
        System.out.println("new nodeId = " + node.getId());
        tx.success();
    } catch (Exception e) {
        tx.failure();
        e.printStackTrace();
    } finally {
        tx.finish();
        return node;
    }
}

public Node addNodeProperty(Node node, String propertyName, Object propertyValue) {
    Transaction tx = getGraphDb().beginTx();
    try {
        node.setProperty(propertyName, propertyValue);
        tx.success();
    } catch (Exception e) {
        tx.failure();
        e.printStackTrace();
    } finally {
        tx.finish();
        return node;
    }
}

public void shutDown() {
    graphDb.shutdown();
}

public void registerShutdownHook() {
    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            graphDb.shutdown();
        }
    });
}
}

すべてのヘルパー メソッドは、getNode(Long id) および createNode() とほぼ同じ方法で構造化されています。もちろん、もう少しロジックが含まれているものもありますが、これで学習したいだけなので、それほど複雑ではありません。

それでは、最後に私の質問に:
* これは、これらのトランザクションを処理する適切な方法ですか? または、何らかのタイプのトランザクション マネージャーを実装する必要がありますか?
* また、トランザクションごとに shutdown を呼び出す必要がありますか?
* これは、アプリケーション レベルではなく、クライアント セッション レベルで処理する必要があるのではないでしょうか?

このクラスは、サーバー (http/jvm) が再起動されるまで (jsf、applicationScope に精通している場合) サーバーのメモリにとどまるため、トランザクションごとにシャットダウンを呼び出すのは少しやり過ぎのようです。

編集:どちらの回答も私の質問にある程度回答しているため、以下のどの回答を承認済みとしてマークするかについて実際に悩んでいます。ですから、なぜ回答が受け入れられなかったのか疑問に思っているなら、それが理由です。

4

3 に答える 3

5

GraphDatabaseService を SQLConnection などと見なさないでください。これは長寿命のインスタンスであり、頻繁に停止し始めると、長寿命のそのようなインスタンスから得られる多くの利点が失われ、多くの不必要なオーバーヘッドが課せられます。

そのように tx.failure() を呼び出す必要はありません。シンプルな:

パブリック ノード createNode() {
    トランザクション tx = getGraphDb().beginTx();
    試す {
        ノード node = graphDb.createNode();
        System.out.println("新しい nodeId = " + node.getId());
        tx.success();
        ノードを返します。
    } 最後に {
        tx.finish();
    }
}

success() が呼び出された場合にのみトランザクションが成功したと見なされ、それ以外の場合はロールバックされるため、問題ありません。また、トランザクションで読み取り操作を実行する必要はまったくないため、次のようになります。

public Node getNode(Long id) {
    return getGraphDb().getNodeById(id);
}

十分です。

于 2012-08-06T11:15:41.923 に答える
1

あなたの取引処理は問題ないようです。いいえ、トランザクションごとにシャットダウンしないでください。シングルトンを介してneo4j dbへのハンドルを取得するだけです-上記のことから、このクラスが再インスタンス化されているように見えますが、それが問題です.neo4jへの別の接続を開こうとしていますが、それは許可されていません.

于 2012-08-04T11:13:54.940 に答える