2017-02-07 11 views
2

Есть ли способ создать блокировки в Couchdb при выполнении массового сохранения? Я считаю, что нет встроенного метода для достижения этого, но можно ли решить это с помощью обходного пути? У меня есть сценарий, похожий на следующее (я использую Node.js для взаимодействия с базой данных CouchDB):Заблокированные документы Couchdb при массовом обновлении

Пользователь платит другому пользователю при создании нового объекта документа следующим образом:

{ 
    _id: SOMEID 
    type: "PAYMENT" 
    username: SOMEUSER 
    paidto: ANOTHERUSER 
    amount: 10 
} 

Когда сохраняется мне нужно для обновления оставшегося баланса у пользователя есть в его/ее account document (вычтите 10 из его кошелька). Затем я сохраняю оба этих документа сразу с bulk_docs (недавно созданный transaction document и обновленный account document).

Но если во время этого процесса пользователь вносит изменения в account document через какой-либо другой метод (скажем, в другой вкладке) мы имеем проблему, когда новый transaction document сохраняется в то время как account document не может быть обновлен. Это создает большую проблему и проблему согласованности.

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

Я пытаюсь развернуть Couchdb - это среда, в которой согласованность между документами очень важна, но без блокировок это оказывается очень сложным.

ответ

1

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

Нельзя. Банковское дело - very well documented example для баз данных документов. Лучшая практика заключается в том, чтобы хранить только транзакции в виде документов и рассматривать баланс счета как запрос к представлению (транзакций, индексированных по учетным записям).

Карта

function(o) { 
    if (o.paidto && o.amount && o.username) { 
    emit(o.paidto, o.amount); 
    emit(o.username, -o.amount); 
    } 
} 

Уменьшить
_sum 

Query
GET /mydb/_design/mydesign/_view/myview/?group=true&key=SOMEUSER 
+0

Да, но как вы решить условия гонки? Допустим, вы не можете тратить больше, чем вы, то есть сумма не может быть отрицательной. В настоящее время у вас 20 кошелек. Теперь предположим, что два «затратных» процесса запускаются одновременно с каждым рисунком 20 $. Они будут проверять, сколько у них есть в кошельке, а затем инициировать трат. Если второй процесс проверяет и завершает транзакцию, в то время как первый из них только что проверил и собирается завершить транзакцию, первый может привести к переходу кошелька на минус -20 $? – pewpewlasers

+0

@pewpewlasers Хороший вопрос. Моя первая мысль заключалась в том, чтобы подражать тому, как это возможно сделать в банке: транзакция была создана, но затем был отправлен ордер на недействительность. Вы можете сделать это, например, с помощью процесса [NodeJS, слушающего API _xanges API] (https://github.com/iriscouch/follow), запрашивающего представление, чтобы получить баланс учетной записи соответствующего пользователя и отправку ордера на недействительность (специальный документ), если он превышает лимит овердрафта. –

+0

Спасибо за предложение, я попробую ваш метод. – pewpewlasers

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