2009-07-01 3 views
1

Avertissement: Je l'ai déjà demandé this question, mais sans l'exigence de déploiement . J'ai obtenu une réponse qui a obtenu 3 upvotes, et quand j'ai édité la question pour inclure l'exigence de déploiement la réponse alors est devenue non pertinente. La raison pour laquelle je suis resubmitting est parce que SO considère la question d'origine «répondu», même bien que je n'ai pas de réponse significative upvoted significative. J'ai ouvert un uservoice submission à propos de ce problème. La raison pour laquelle j'ai été repostée est que StackOverflow considère que la question d'origine a été répondue, donc elle n'apparaît pas dans l'onglet 'questions non répondues'.Lock Service sur Périphérie MySql/GigaSpaces/Netapp

Quel service de verrouillage distribué utiliseriez-vous?

Les exigences sont:

  1. Une exclusion mutuelle (verrouillage) qui peut être vu à partir de différents processus/machines
  2. sémantique serrure ... PUBLIE
  3. libération de verrouillage automatique après un certain délai - si le verrouillage détenteur meurt, il sera automatiquement libéré après X secondes
  4. Mise en œuvre Java
  5. Déploiement facile - ne doit pas obligatoirement compl déployé au-delà de Netapp, MySql ou GigaSpaces. Doit bien jouer avec ces produits (en particulier GigaSpaces - c'est pourquoi TerraCotta a été exclu).
  6. Très agréable d'avoir: la mise en œuvre .Net
  7. Si c'est gratuit: la détection Deadlock/atténuation

Je ne suis pas intéressé par des réponses comme « il peut être fait sur une base de données », ou « il peut être fait sur JavaSpaces "- Je sais. Les réponses pertinentes ne doivent contenir qu'une implémentation prête, prête à l'emploi et éprouvée.

+0

Je ne comprends pas pourquoi vous ne modifiez pas l'autre question, et si une réponse qui répond à vos exigences révisées est ajoutée, acceptez-la; il n'a pas vraiment d'importance qu'une autre réponse a plus de votes upvotes. Il est très courant (et accepté) que certaines réponses soient rendues non pertinentes par des modifications à la question. – erickson

+0

Parce qu'il est considéré comme 'répondu' (réponse augmentée), il n'apparaît pas dans l'onglet 'questions non répondues'. – ripper234

Répondre

1

est ici les grandes lignes d'une réponse basée GigaSpaces qui répond à vos critères, en fonction de ce que vous entendez dans les critères 3. Je travaille avec GigaSpaces de .Net, pas Java:

Créer une classe de verrouillage avec un SpaceID + propriété SpaceRouting Iding ce qui est verrouillé et DataMember propriété bool débloqué:

sealed public class IdLockTrans 
{ 
    [SpaceID] 
    [SpaceRouting] 
    public string ID 
    { 
     get; 
     set; 
    } 

    [DataMember] 
    public bool Unlocked 
    { 
     get; 
     set; 
    } 

    public IdLockTrans(Id id) 
    { 
     ID = id.ID; 
    } 

    public IdLockTrans() 
    { 
    } 
} 

Vous utiliserez le temps de location de GigaSpaces pour la libération de verrouillage après un certain délai . Cela entraînera GigaSpaces à supprimer les objets IdLockTrans de l'espace automatiquement après qu'ils ont été inactifs pendant la période de délai . L'absence d'IdLockTrans pour un ID signifie que l'ID est déverrouillé.

Votre classe de casier définira et initialiser ces membres de la classe

private readonly ISpaceProxy _proxy; 
    private readonly long _leaseTime; 

    public override bool Lock(Id id, long timeout) 
    { 
     bool locked; 
     IdLockTrans lockTransTemplate = new IdLockTrans(id); 
     // Assume that this is a new id. 
     try 
     { 
      _proxy.Write(lockTransTemplate, null, _leaseTime, 0, UpdateModifiers.WriteOnly); 
      locked = true; 
     } 
     catch (EntryAlreadyInSpaceException) 
     { 
      using (ITransaction tx = _proxy.CreateLocalTransaction()) 
      { 
       try 
       { 
        lockTransTemplate.Unlocked = true; 
        IdLockTrans lockTrans = _proxy.Take(lockTransTemplate, tx, timeout); 
        locked = (lockTrans != null); 
        if (lockTrans != null) 
        { 
         lockTrans.Unlocked = false; 
         _proxy.Write(lockTrans, tx, _leaseTime, 0, UpdateModifiers.WriteOnly); 
        } 
        tx.Commit(); 
       } 
       catch 
       { 
        tx.Abort(); 
        throw; 
       } 
      } 
     } 
     return locked; 
    } 

    public override void Unlock(Id lockedId) 
    { 
     IdLockTrans lockTrans = new IdLockTrans(lockedId); 
     lockTrans.Unlocked = true; 
     try 
     { 
      _proxy.Update(lockTrans, null, _leaseTime, 0, UpdateModifiers.UpdateOnly); 
     } 
     catch (EntryNotInSpaceException) 
     { 
      throw new Exception("IdLockTrans for " + lockTrans.ID 
       + " not found on Unlock. Lock time exceeded lease time."); 
     } 
    } 
+0

C'est ce que j'ai fini par mettre en œuvre. Je ne peux pas publier le code source parce que c'est la propriété de l'entreprise, mais c'est l'idée générale. – ripper234

0

Si vous cherchez encore, jetez un oeil à Apache Zookeeper:

ZooKeeper est un service centralisé pour maintenir des informations de configuration, nommer, fournir une synchronisation distribuée et fournir des services de groupe. Tous ces types de services sont utilisés sous une forme ou une autre par des applications distribuées.

La documentation de Zookeeper fournit des exemples de how to build a Lock service au-dessus de Zookeeper.

0

Utilisez mysql pour verrouiller une clé unique est très simple.

Hypothèse 1:

Vous utilisez la transaction et votre niveau d'isolation est en lecture engagée.

Hypothèse 2: Vous verrouillez votre thread de traitement par une clé unique et libérez-le lorsque votre transaction est validée.

Ensuite, vous pouvez utiliser cette sql comme la distribution de verrouillage:

Insérer dans distributed_lock (clés) valeurs (# {key}) sur la touche ON DUPLICATE KEY UPDATE = clé;

Questions connexes