2013-08-28 1 views
4

Я немного запутался в терминах транзакции. Предположим, что в транзакции A мы имеем две команды C1 и C2 и то же самое в транзакции B. Теперь обе транзакции приходят в то же время, то Правильны ли эти наблюдения?Что означает транзакция в ссылке с базой данных neo4j

  1. Все команды транзакции A C1 и C2 будет сделано в первую очередь (предполагая ввести первый), то будет выполняться только команды транзакции B.

  2. Любая команда транзакции A или B может быть выполнена, но с уверенностью, что если какая-либо из команд завершится сбой какой-либо из транзакций, то эта транзакция будет откатом.

  3. Если второй случай верно, то в транзакции по умолчанию, она не заблокировать любой ресурс до его завершения

  4. Если первый случай не верно, то по умолчанию транзакции УДЕР на ресурсы до их завершения.

благодаря

Amit Аггарваль

ответ

7

Мы должны говорить о "я" в ACID (Neo4j является ACID-совместимый), который выступает за "изоляции". Уровень изоляции говорит вам, как много данных друг друга одновременно просматривают транзакции.

Уровень изоляции по умолчанию в Neo4j является «прочитанным». Это означает, что A не увидит, что данные B записаны, до тех пор, пока B не зафиксируется. Это достигается с помощью автоматической блокировки, которая работает следующим образом:

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

Однако некоторые аномалии могут произойти на этом уровне изоляции, один из которых называется «потерянное обновление».

Для иллюстрации, пусть c будет вашим значением счетчика (я понимаю, что атомный счетчик - это то, что вы в конечном итоге после). Обе операции увеличивают счетчик на 1.

c=0 
Tx1 reads c=0 (read locks c) 
Tx2 reads c=0 (read locks c) 
Tx1 writes c=1 (write locks c) 
Tx1 commits (unlocks c) 
Tx2 writes c=1 (because it thinks c is still 0, write locks c) 
Tx2 commits (unlocks c) 

Обновление Tx1 сделано потеряно.

Чтобы предотвратить это, вам необходимо изменить уровень изоляции на «повторяемое чтение» путем блокировки записи объектов, которые вы собираетесь явно изменить перед началом, перед чтением их текущего значения. Таким образом, они не будут изменяться никакими другими одновременно выполняющимися транзакциями.

c=0 
Tx1 write locks c 
Tx1 reads c=0 
Tx2 tries to write lock c, has to wait 
Tx1 writes c=1 
Tx1 commits (unlocks c) 
Tx2 write locks c (because it now can) 
Tx2 reads c=1 
Tx2 writes c=2 
Tx2 commits (unlocks c) 

Надеюсь, что все станет понятнее.

+0

Кто-нибудь знает, как это сделать? (в запросе Cypher/Neography) – mirelon

+0

Я боюсь, что невозможно использовать Cypher для явного приобретения блокировок на данный момент. Единственный способ сделать это - это основной API (Java). –

+1

Это немного громоздко, но вы * можете * использовать Cypher для явного приобретения блокировки записи на узле или в отношении отношения. Вы можете приобрести его, временно установив свойство throwaway на узел/связь.И затем, до конца запроса, вы можете удалить это свойство throwaway. – cybersam

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