2013-04-30 2 views
1

Для записи я использую Neo4j 2.0.0-M02.Вложенные транзакции в Neo4j

В настоящее время у меня есть метод, который может искать узлы с меткой «Пользователь» на их идентификаторе пользователя, который хранится в графе как свойство «id» узла. Это происходит в транзакции, так как это автоматически закрывает ResourceIterator.

Теперь я хочу создать отношения между двумя пользователями. Все, что у меня есть, это их идентификатор пользователя. Теперь я, очевидно, хотел бы повторно использовать метод, который ищет пользователей по их идентификатору. И есть три способа, о которых я могу думать.

Первый из них является очевидным. Извлеките два узла с уже существующим методом. Затем вызовите метод, который создает отношения между ними. Очевидно, это происходит и в транзакции, поэтому для этого потребуется три транзакции. Не так эффективно.

Второй способ заключается в повторном использовании кода (а не метода) в новом методе, который создает связь. Таким образом, я могу сделать все это в одной транзакции, но я дублирую код, который не является действительно хорошей практикой для разработчиков.

Третьим является вызов существующего метода дважды внутри транзакции нового метода, который создает взаимосвязь. Таким образом, мой код по-прежнему можно использовать повторно, но я не уверен, как вложенные транзакции работают в Neo4J. Не будут ли проигнорированы транзакции из существующего метода, поскольку уже существует существующая транзакция? Это решило бы мою проблему.

Если нет, я должен переосмыслить, где я управляю своими транзакциями. Я знаю, что обычно лучше управлять ими в сервисах, чем в DAO, но я хотел бы оставить материал Neo4j из моих классов обслуживания.

ответ

5

Третий вариант заключается в том, как он будет работать, поскольку в neo4j нет действительно вложенных транзакций, а вместо этого очень мелкие транзакции, где есть существующая внешняя транзакция, поэтому практически нет накладных расходов.

 
Transaction tx = db.beginTx(); 
try 
{ 
    otherMethod(db); 
    tx.success(); 
} 
finally 
{ 
    tx.finish(); 
} 

private void otherMethod(GraphDatabaseService db) 
{ 
    Transaction tx = db.beginTx(); 
    try 
    { 
     // do some other stuff... 
     tx.success(); 
    } 
    finally 
    { 
     tx.finish(); 
    } 
} 

В приведенном выше примере вызов otherMethod() будет работать с существующей транзакцией или без нее. Если существует транзакция, то выполняемые ею операции будут иметь место, но если нет существующей транзакции, она будет создана. Так что оба будут работать.

+0

Так что, если в otherMethod произошла ошибка, вся транзакция будет отброшена, верно? –

+0

Сделка будет отменена, если вызвана tx.failure() ИЛИ NOT tx.success(). Поэтому в этом случае да –

Смежные вопросы