Note that there are some explanatory texts on larger screens.

plurals
  1. POMongoDB Database Semaphores and Node.js Process.NextTick()
    primarykey
    data
    text
    <p>This may be a vary bad idea, or a possible solution that we have to a database concurrency problem.</p> <p>We have a method that is called to do an update of a mongo record. We are seeing some concurrency problems - process A reads the record, process B reads the record, process A makes mods and saves the record, process makes B mods and saves the record. Because B reads after A, before A writes, it doesn't know about the changes A made, and we lose the data from A.</p> <p>I'm wondering if we could not use a database semaphore, basically a field on the collection, that is a boolean. If we read the record at the start of the method, and the field is true, it's being edited. At that point, re-call the method using process.nexttick(), with the same data. Otherwise, set the semaphore, and carry on.</p> <p>There would still be a bit of time between the read and the save, but it should be/could be faster than what we are doing now.</p> <p>Be something like this. Any thoughts, anyone done anything like this? Will it even work?</p> <pre><code>function remove_source(service_id,session, next) { var User = Mongoose.model("User"); /* get the user, based on the session user id */ User.findById(session.me,function(err,user_info) { if (user_info.semaphore === true) { process.nextTick(remove_source(service_id,session,next)); } else { user_info.semaphore = true; user_info.save(function(err,user_new) { if (err) next(err,user_new); else continue_on(null,user_new); }); } function continue_on(user_new) { etc....... } </code></pre> <p>Edit: New Code:</p> <p>The function now looks as follows. I'm doing individual updates to the arrays. This of course means that I now have the possibility, if the transaction fails between the first and second transactions, of having data out of sync. I'm thinking that I could simply resave the user object that I retrieved on entry into the function, overwriting my changes. I don't know if Mongoose/Mongo will not do the save if I have not changed that object, will have to try and see. Any more thoughts?</p> <pre><code> var User = Mongoose.model("User"); /* get the user, based on the session user id */ User.findById(session.me,function(err,user_info) { if (err) { next(err,user_info,null); return; } if (!user_info || user_info.length === 0) { next(_e("ACCOUNT_NOT_FOUND"),"user_id: " + session.me); return; } var source_service_info = _.where(user_info.credentials, {"source_service_id": service_id}); var source_service = source_service_info.source_service; User.findByIdAndUpdate(session.me,{$pull: {"credentials": {"source_service_id": service_id}}},{},function(err,user_credential_removed) { if (err) { next(err,user_info,null); return; } User.findByIdAndUpdate(session.me,{$pull: {"criteria": {"source_service": source_service}}},{},function(err,user_criteria_removed) { if (err) { next(err,user_info,null); return; } else { next(null,user_criteria_removed); } }); }); }); </code></pre> <p>};</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload