Si vous êtes prêt à verrouiller toutes les mises à jour toutes les trois collections pendant que vous mettez à jour la « table de jointure », vous pourriez mettre en œuvre ce avec le verrouillage de l'application.
Version courte: vous créez une collection 'locks'. Chaque client doit acquérir un «verrou d'écriture» avant de mettre à jour l'une des trois collections cA, cB ou cC. Il le fait en mettant à jour un document dans la collection 'locks'. Lorsque vous êtes prêt à effectuer votre mise à jour par lots, vous acquérez le «verrouillage en écriture», effectuez la mise à jour et libérez le verrou.
Voici un exemple de code simple qui implémente le verrouillage. Notez qu'il existe plusieurs limites à ce code:
- Il n'y a pas de détection de blocage ou la prévention
- Il n'y a pas de délai de verrouillage
- Tentative de rebloquer une ressource verrouillée toujours échouer, même si le verrou a été précédemment acquise avec succès
La fixation de ces limitations est laissée à l'utilisateur.
XDB = db.mylocks;
/*
* Set up the locking collection
*/
function setup_locking(res_name) {
var doc = { _id: res_name, state: "UNLOCKED", locker: null };
// upsert to create document if it does not exist
XDB.update({id: res_name}, doc, true);
}
/*
* Lock the resource named 'res_name' by process named 'proc'
*
* Returns 'true' if resource was acquired, 'false' if it was not acquired
*/
function lockit(res_name, proc) {
/*
* 1) Change state to LOCKED if & only if it was previously UNLOCKED
*/
ret = XDB.findAndModify({
query: { _id:res_name, state:"UNLOCKED" } ,
update: {"$set": { state:"LOCKED", locker: proc } },
fields: { state:1, locker:1 },
new: true
}
);
/*
* Return 'true' if this process acquired this resource
*/
if (ret && (ret.state == "LOCKED") && (ret.locker == proc))return true;
/*
* 2) Failed to acquire this resource
*/
return false;
}
/*
* Unlock the resource named 'res_name' previously held by 'proc'
*/
function unlockit(res_name, proc) {
// Unlock resource if this process had previously acquired it
XDB.findAndModify({
query: { _id:res_name, locker: proc, state:"LOCKED" } ,
update: {"$set": { state:"UNLOCKED", locker: null } },
}
);
}
/*
* Check to see if resource 'res_name' is currently held by 'proc'
*/
function has_lock(res_name, proc) {
res = XDB.findOne({_id: res_name, locker:proc});
if (res == null) return false;
return true;
}
XDB.drop();
setup_locking('collectionA');
result = lockit('collectionA', 'app1');
print("1: result =", result);
result = lockit('collectionA', 'app2');
print("2: result =", result);
result = lockit('collectionA', 'app1');
print("3a: result =", result);
result = has_lock('collectionA', 'app1');
print("3b: result =", result);
result = has_lock('collectionA', 'app2');
print("3c: result =", result);
unlockit('collectionA', 'app1');
result = lockit('collectionA', 'app2');
print("4: result =", result);
MongoDB n'a aucune notion de snapshots. –
par instantané, je veux dire copier une collection: db.cA.copyTo ("cA_snapshot") –
On dirait que vous voulez un SGBDR. Vous pouvez faire une requête instantanée sur les collections qui pourraient être sauvegardées pendant que le processus est terminé: http://docs.mongodb.org/manual/reference/method/cursor.snapshot/#cursor.snapshot mais cela ne fonctionnera pas avec Partage autre que tout ce que je peux recommander est de ne pas télécharger 8 Go de données régulièrement. – Sammaye