Как обойти отсутствие транзакций в MongoDB?
— передача денег от А к В с проверками и откатами;
Просто не надо использовать mongodb для этого. Не получится. mongo написана для хранения не ценных данных, потери которых мало кого интересуют. Поэтому, например, mongo по-умолчанию сразу возвращает успех, не дожидаясь записи в базу.
— покупка товара (уходит со склада и приходит пользователю в заказы, причем так, чтобы 2 пользователя не купили последний товар со склада, а владелец товара не успел изменить цену, пока пользователь покупал (условно говоря лок на товар))
Это скорее всего можно сделать атомарными операциями. Но если надо, локи организуются с помощью поля «заблокирован до», уникального индекса на id товара и запросов вида
upsert(«объект с установленным полем времени блокировки», «время блокировки меньше текущего времени»)
Если лока еще нет, то он будет создан. Если лок есть но просрочен (захвативший его процесс упал), то запрос обновит такую запись. Если лок захвачен, то запрос попытается создать новый lock, но упадет из-за дубликата ключа в индексе.
Как я понимаю, mongodb тут хорошо именно в том ключе, что можно для разных типов товара задавать профильные конкретно для него свойства и не описывать их заранее. И есть некий набор свойств, присущий всем товарам (как количество, стоимость и т.д.). В этом смысле, вам действительно было бы удобнее убрать эти универсальные свойства в РСУБД и эта задача явно не для mongodb.
Сам не пользовался, но судя по анонсу PostgreSQL 9.2 поддерживает json field и возможно это подойдёт для такой задачи.
Но, похоже есть некоторые сложности с поиском по данным этого поля.
Вот, к примеру, вопрос (с решением) на stackoverflow:
stackoverflow.com/questions/10560394/how-do-i-query-using-fields-inside-the-new-postgresql-json-datatype