Question

  

Disclaimer : Je l'ai déjà demandé cette question , mais sans   exigence de déploiement. Je suis un   réponse qui a obtenu 3 upvotes, et quand je   modifié la question d'inclure l'exigence de déploiement de la réponse alors   est devenue sans objet. La raison pour laquelle je suis   Resoumission est parce considère SO   la question initiale répondit ', même   bien que je me suis pas significatif upvoted   répondre. J'ai ouvert un uservoice   soumission sur ce problème.   La raison pour laquelle je Republiée est donc StackOverflow examiner la question initiale a répondu, il ne se présente pas sur l'onglet « questions sans réponse ».

Ce qui a distribué verrouillez 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 titulaire de verrouillage meurt, il sera automatiquement libéré après X secondes
  4. implémentation Java
  5. Déploiement facile - ne doit pas nécessiter le déploiement compliqué au-delà soit 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: détection / atténuation Deadlock

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. Réponses pertinentes ne doivent contenir un prêt, hors-the-box, la mise en œuvre éprouvée.

Était-ce utile?

La solution

Voici l'esquisse 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 une propriété SpaceID + SpaceRouting Iding ce qui est verrouillé et une propriété bool DataMember 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 temps libre. Cela entraînera GigaSpaces supprimer des objets IdLockTrans de l'espace automatiquement après avoir été inactif pendant le délai d'attente période. L'absence d'un 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.");
        }
    }

Autres conseils

Votre implémentation .Net est très proche existant de la serrure de la boîte / déverrouiller API fournie avec l'API Java. Voir: http://www.gigaspaces.com/docs/JavaDoc8 0,0 / org / Openspaces / core / DefaultGigaMap.html

Vous pouvez trouver le code source pour cette classe Java dans le cadre du fichier gs-openspaces-src.zip fourni avec le produit. Ayant la même chose avec GigaSpaces API .Net doit être straightfwd.

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

  

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

La documentation Zookeeper fournit des exemples de comment construire un service de verrouillage au-dessus de Zookeeper.

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

Hypothèse 1:

Vous utilisez la transaction et votre niveau d'isolement est lu engagé.

Hypothèse 2: Vous verrouillez vous fil de traitement par une clé unique et relâchez lorsque votre transaction engagée.

Ensuite, vous pouvez utiliser SQL comme verrou distribuer:

Insérer dans distributed_lock (clé)         valeurs (# {key}) Duplicate KEY clé UPDATE = touche;

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top