Можно ли реализовать Multi-Version Concurrency Control (MVCC) поверх MongoDB?
MongoDB для меня отличная база данных. Однако есть случаи, когда мне действительно нужны атомарные многодокументные транзакции. Например, чтобы перевести вещи (например, деньги или репутацию) между счетами, и это должно либо полностью преуспеть, либо полностью провалиться.
Интересно, можно ли было бы взаимодействовать с MongoDB через библиотеку, реализующую шаблон управления параллелизмом MultiVersion.
Насколько это было бы плохо в отношении выступлений? Было бы возможно и выгодно использовать гибридный подход, используя библиотеку 'mongo-mvcc' только при необходимости и традиционное соединение с БД при работе только с одним документом, или это нарушит работу mvcc?
6 ответов
Простейшим способом является использование блокировок (двухфазная фиксация), хотя в некоторых случаях это не очень эффективно. Для более высокого уровня параллелизма на вершине Mongo может быть реализована какая-то MVCC. Эта статья содержит хорошее описание:
http://highlyscalable.wordpress.com/2012/01/07/mvcc-transactions-key-value/
Денежная транзакция может быть осуществлена посредством двухэтапной фиксации: http://www.mongodb.org/display/DOCS/two-phase+commit
Существует реализация MVCC на MongoDB, доступная сейчас на GitHub:
MongoDB не предназначен для работы с транзакциями. Существует действительно хорошее обсуждение того, как вы могли бы реализовать это по адресу: http://kylebanker.com/blog/2010/04/30/mongodb-and-ecommerce/
Вы можете создать коллекцию версий и иметь документ для последней зафиксированной версии.
Атомарно обновите этот документ с помощью метки времени чтения (rts), которая не является меткой времени, основанной на времени, а монотонно увеличивающимся числом, когда код вашего приложения считывает документ из коллекции.
Перед обновлением коллекции извлеките этот документ коллекции версий и проверьте, есть ли отметка времени чтения ниже вашей текущей транзакции, если есть, прервите чтение или запись.
Обновите документ версий, если вы хотите «опубликовать» с помощью lastCommit версию записи и сделать ее видимой.
Вы должны «видеть» только данные транзакций, которые меньше или равны номеру последней зафиксированной транзакции.
Я реализовал MVCC на Java в этом репозитории.
Хорошо, когда вам нужны реальные транзакции, вы используете RDBMS, которые предназначены для их поддержки:) NoSQL быстрее и более масштабируемы, главным образом потому, что они не поддерживают транзакции.
Если вам нужны оба варианта, может быть, стоит иметь транзакционный уровень для поддержки транзакций и уровень NoSQL для других целей? В некоторых случаях не должно быть сложностью создать гибридную систему, используя, например, MongoDB и PostgreSQL