1

私は Neo4j を使い始めましたが、同時に読んでいるノードのプロパティを更新すると、非常に悪い動作に気付きました。私が書いた clojure コードは、Neocons ライブラリを使用して Neo4j と通信します。

(ns ams.utils.t.test-cypher-error
  (:require [clojurewerkz.neocons.rest :as rest]
            [clojurewerkz.neocons.rest.nodes :as nodes]
            [clojurewerkz.neocons.rest.cypher :as cypher]))

(rest/connect! "http://192.168.0.101:7474/db/data")

(def counter-id (:id (nodes/create {:counter 0})))

(defn update-counter [] (cypher/query "START c = node({id}) SET c.counter = c.counter + 1 RETURN c.counter as counter" {"id" counter-id}))

(doall (apply pcalls (repeat 10 update-counter)))

(println "Counter:" ((comp :counter :data) (nodes/get counter-id)))

(nodes/destroy counter-id)

結果を推測してください:

Counter: 4

5 の場合も 4 の場合もありますが、ここで問題が発生します。節STARTSET節の間でカウンターの値が変更されますが、cypher はそれをキャッチしません!

ここで2つの質問:

  • 私は何か間違ったことをしていますか?
  • Neo4j に実行可能なユニークなカウンターレスト生成アルゴリズムはありますか?

Neo4j のバージョンは 1.9RC1 です。よろしくお願いします。

4

1 に答える 1

4

あなたが直面している問題は、neo4j に暗黙的な読み取りロックがないことです。そのため、次のようなことが時々起こります。

  1. クエリ 1 の開始
  2. クエリ 1counterは値を 3 として読み取ります
  3. クエリ 1 はcounter値を 3+1 = 4 に設定します
  4. クエリ 2 開始
  5. クエリ 2counterは値を 4 として読み取ります
  6. クエリ 2 はcounter値を 4+1 = 5 に設定します

そして、次のことが時々起こります。

  1. クエリ 1 の開始
  2. クエリ 2 開始
  3. クエリ 1counterは値を 3 として読み取ります
  4. counterクエリ 2は値を 3 として読み取ります
  5. クエリ 1 はcounter値を 3+1 = 4 に設定します
  6. クエリ 2 はcounter値を 3+1 = 4 に設定します

読み取りロック データベース (ほとんどの SQL サーバーなど) では、状況 #2 は発生しません。クエリ 2 が開始され、クエリ 1 がコミットまたはロールバックされるまでブロックされます。

読み取りロックを明示的に設定する方法はあるかもしれませんが、REST API 経由ではできませんトランザクション APIは有望に見えますが、必要なものが得られるかどうかは完全にはわかりません。また、REST 経由ではサポートされていません。

于 2013-04-24T16:19:30.340 に答える