Ні. CouchDB використовує модель "оптимістичної одночасності". Найпростішими словами, це просто означає, що ви надсилаєте версію документа разом із вашим оновленням, а CouchDB відхиляє зміни, якщо поточна версія документа не відповідає тому, що ви надіслали.
Насправді це оманливо просто. Ви можете переробити багато звичайних сценаріїв на основі транзакцій для CouchDB. Вам все одно потрібно викидати свої знання домену RDBMS, вивчаючи CouchDB. Корисно підходити до проблем з більш високого рівня, а не намагатися формувати Couch до світу, заснованого на SQL.
Ведення обліку товарно-матеріальних цінностей
Проблема, яку ви окреслили, - це в першу чергу проблема з інвентаризацією. Якщо у вас є документ, що описує товар, і він містить поле для "наявної кількості", ви можете вирішити такі проблеми, як:
- Отримайте документ, зверніть увагу на
_rev
властивість, яку CouchDB надсилає
- Зменште поле кількості, якщо воно більше нуля
- Відправте оновлений документ назад, використовуючи
_rev
властивість
- Якщо
_rev
збігається із збереженим на даний момент номером, будьте готові!
- Якщо виник конфлікт (коли
_rev
не збігається), завантажте найновішу версію документа
У цьому випадку є два можливих сценарії відмови, про які слід подумати. Якщо найновіша версія документа має кількість 0, ви обробляєте це так само, як і в СУБД, і попереджаєте користувача, що він фактично не може придбати те, що хотів придбати. Якщо остання версія документа має кількість більше 0, ви просто повторюєте операцію з оновленими даними та починаєте спочатку. Це змушує вас робити трохи більше роботи, ніж RDBMS, і може трохи дратувати, якщо часто виникають суперечливі оновлення.
Тепер відповідь, яку я щойно дав, передбачає, що ви збираєтеся робити речі в CouchDB приблизно так само, як і в RDBMS. Я міг би підійти до цієї проблеми дещо інакше:
Я б почав з документа "головного продукту", який включає всі дані дескриптора (ім'я, зображення, опис, ціна тощо). Тоді я додав би документ "інвентарний квиток" для кожного конкретного екземпляру, з полями для product_key
та claimed_by
. Якщо ви продаєте модель молотка і маєте їх продати 20, у вас можуть бути документи з ключами, наприклад hammer-1
,hammer-2
і т.д., для подання кожного доступного молотка.
Потім я створив подання, яке дасть мені список доступних молотків, із функцією зменшення, яка дозволяє побачити "загальний". Вони повністю зняті з манжети, але повинні дати вам уявлення про те, як би виглядав робочий вигляд.
Карта
function(doc)
{
if (doc.type == 'inventory_ticket' && doc.claimed_by == null ) {
emit(doc.product_key, { 'inventory_ticket' :doc.id, '_rev' : doc._rev });
}
}
Це дає мені список доступних "квитків" за ключами продукту. Я можу захопити групу з них, коли хтось хоче придбати молоток, потім повторювати, надсилаючи оновлення (за допомогою id
і _rev
), доки я успішно не заявлю заявку (раніше заявлені квитки спричинять помилку оновлення).
Зменшити
function (keys, values, combine) {
return values.length;
}
Ця функція зменшення просто повертає загальну кількість незатребуваних inventory_ticket
предметів, тому ви можете визначити, скільки "молотків" можна придбати.
Застереження
Це рішення представляє приблизно 3,5 хвилини загального обдумування конкретної проблеми, яку ви подали. Можуть бути кращі способи зробити це! Тим не менш, це істотно зменшує суперечливі оновлення та зменшує необхідність відповідати на конфлікт новим оновленням. Згідно з цією моделлю, у вас не буде декількох користувачів, які намагаються змінити дані при первинному введенні товару. У найгіршому випадку у вас буде кілька користувачів, які намагаються претендувати на єдиний квиток, і якщо ви захопили кілька із них, ви просто переходите до наступного квитка та повторюєте спробу.
Посилання: https://wiki.apache.org/couchdb/Frequently_asked_questions#How_do_I_use_transactions_with_CouchDB.3F