2013-01-04 6 views
-1

J'ai un db avec des collections cA, cB et cC. J'ai besoin de mettre à jour la base de données toutes les 5 minutes d'une manière transactionnelle (cB est une relation n-m de cA et cC). Comme il ne semble pas facile d'émuler transactions with mongo, je pense que je pourrais créer des instantanés (db.cA.copyTo ("cA_snapshot")) de cA, cB et cC avant de lancer le processus de téléchargement et retourner les requêtes de lecture sur l'instantané tout en faire les inserts. Malheureusement, la taille des collections dépasse les 8 Go et le fait de faire la collection.copyTo semble prendre trop de temps.mongo db réplication de la collection pour éviter le manque de transactions

Alors, existe-t-il un moyen d'y parvenir en utilisant la journalisation? Disons que je prends le coût pour créer l'instantané des collections une fois au démarrage. Ensuite, est-ce que je peux relire manuellement les éléments de journalisation de cA sur cA_snapshot?

grâce

+0

MongoDB n'a aucune notion de snapshots. –

+0

par instantané, je veux dire copier une collection: db.cA.copyTo ("cA_snapshot") –

+0

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

Répondre

0

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); 
Questions connexes