Это база данных без схемы, так что воспользуйтесь ей! :-) Вы можете использовать утку, но добавив поле к любому типу документа, который распознается по типам. Убедитесь, что вы используете имена, которые не используются в документе.
В любом документе с задачей (например, отправка электронного письма) добавьте массив tasks: []
. Когда вы обновляете документ, и вам нужно, чтобы с ним связалась «атомарная» вещь, поместите задачу в эту очередь. Например, для электронной почты: { email: "cust@client.com", at: 0 }
. Фоновый процесс опрашивает эти задачи, устанавливает срок их действия в будущем, выполняет их и удаляет их. Если что-то не получится, задание прекратит работу и будет перезапущено. Таким образом, вы можете отправить два письма, но это более или менее неизбежно для почты, даже для транзакций.
вы можете запустить это в оболочке mongodb:
#db.orders.remove()
db.orders.save( { name: "abc", tasks : [ { email: 'a@dom.com', at: 0}, { email: 'b@dom.com', at: 0} ] })
db.orders.save( { name: "def", tasks : [ { email: 'c@dom.com', at: 0}] })
now = 10; future = 100; me = "some unique identifier for this scanning process"
while ( true ) {
task = db.orders.findAndModify({
query: { "tasks.at": { $lt: now }},
update : { $set : { "tasks.$.at": future, "tasks.$.who": me } },
fields: { "tasks":1},
new: true } )
if ( !task)
break;
for ( var i in task.tasks ) {
if ( task.tasks[i].who === me )
print( "Send email " + task.tasks[i].email )
}
db.orders.update( { _id: task._id }, { $pull: { tasks: { who: me } } } )
}
Посмотрите на http://www.mongodb.org/display/DOCS/findAndModify+Command аналогичный пример.