Как избежать циклических зависимостей между документами в CouchDB - PullRequest
1 голос
/ 07 июля 2010

Мне интересно моделировать отношения между документами в CouchDB. Допустим, у меня есть три документа A, B и C. Эти документы могут ссылаться друг на друга, но есть ограничение приложения, что циклическая зависимость не должна возникать.

Давайте рассмотрим пример (-> это маркер зависимости):

A -> B

C

Два клиента (C1, C2) пытаются изменить одновременно:

C1 = B -> C

C2 = C -> A

Если C1 и C2 будут успешными, будет цикл. Вопрос в том, как это предотвратить?

Я думал об этом, и мне кажется, что мне нужна какая-то крупнозернистая блокировка для документов и атомарного массового обновления. Проблема в атомном массовом обновлении. CouchDB поддерживает массовое обновление, но без отката в случае конфликта версий. Что это значит:

Допустим, у нас есть документ V. Этот документ представляет глобальную версию (грубая блокировка) и содержит версию связанных документов (A, B, C) для данной редакции документа.

V {
  _rev: 1,
  versions: [[A,1],[B,1],[C,1]] 
}

С1 и С2 работают одновременно:

  1. C1 = получить V

  2. C2 = получить V

  3. C1 = получить A.1, B.1, C1

  4. C2 = получить A.1, B.1, C1

  5. C1 = сделать проверку зависимостей (все в порядке)

  6. C2 = сделать проверку зависимостей (все в порядке)

  7. C1 = обновить V относительно предполагаемой зависимости B-> C {версии: [[A, 1], [B, 2], [C, 2]]} (все в порядке)

  8. C1 = обновление B

  9. C2 = попытка обновить V в соответствии с предполагаемой зависимостью C-> A {версии: [[A, 2], [B, 1], [C, 2]]}} (этот шаг не будет выполнен из-за CouchDB оптимистическая блокировка)

Все хорошо и хорошо, пока C1 не сломается между шагами 7. и 8. Теперь массовая вставка / обновление поступает на сцену.

7.) C1 = обновить V относительно предполагаемой зависимости B-> C {версии: [[A, 1], [B, 2], [C, 2]]} (все в порядке) и обновить B

Какое прекрасное решение, к сожалению, оно вообще не работает из-за большой семантики вставки / обновления в CouchDB http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API#Transactional_Semantics_with_Bulk_Updates. Массовая вставка / обновление не является атомарной операцией.

Есть ли обходной путь для этого? Могу ли я как-то обойти это? Я пропустил что-то важное?

Ответы [ 2 ]

0 голосов
/ 16 января 2011

Если я могу добавить здесь 0,02 доллара, отношения действительно не для мира баз данных на основе документов.

Рассмотрите возможность переосмысления модели в терминах «ссылки», как в одном документе, ссылающемся на другой, а в другом - на первый. Это совершенно нормально для документов, но, исходя из реляционного мира, у всех нас есть проблемы с инерцией мышления:)

0 голосов
/ 08 июля 2010

Два клиента (C1, C2) пытаются одновременно Модификация:

C1 = B -> C

C2 = C -> A

Если C1 и C2 будут успешными, будут цикл. Вопрос в том, как предотвратить это?

Это невозможно предотвратить. Что если C1 работает с сервером X, а C2 работает с сервером Y, а X и Y не подключены к сети. Когда X и Y переподключены и реплицируются, оба документа B и C в конечном итоге будут отредактированы.

Это то, что мы имеем в виду, когда говорим, что CouchDB является транзакцией для одного документа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...