Pergunta

Aviso : Eu já pedi esta questão , mas sem a exigência de implantação. Eu tenho um responder que tem 3 upvotes, e quando eu editada a questão para incluir o requisito de implantação, a resposta em seguida tornou-se irrelevante. A razão que eu sou reenviar é porque SO considera à pergunta original 'respondeu', mesmo embora eu não tenho significativa upvoted responda. Abri um uservoice submissão sobre este problema. A razão que eu anunciado é tão StackOverflow considerar a pergunta original respondeu, de modo que não aparecem na guia 'perguntas não respondidas'.

Qual o serviço de bloqueio distribuído você usaria?

Os requisitos são:

  1. A exclusão mútua (bloqueio), que pode ser visto a partir de diferentes processos / máquinas
  2. Bloqueio ... semântica libertação
  3. liberação automática de bloqueio depois de um certo tempo de espera - se morre titular de bloqueio, ele será automaticamente liberada após X segundos
  4. implementação Java
  5. implantação Fácil - não deve exigir a implantação complicado para além quer Netapp, MySql ou GigaSpaces. Deve jogar bem com esses produtos (especialmente GigaSpaces - é por isso terracota foi descartada).
  6. É bom ter: implementação .Net
  7. Se é grátis: Impasse detecção / mitigação

Eu não estou interessado em respostas como "isso pode ser feito ao longo de um banco de dados", ou "isso pode ser feito ao longo JavaSpaces" - Eu sei. respostas relevantes deve conter apenas um, out-of-the-box, implementação pronto comprovada.

Foi útil?

Solução

Aqui está o esboço de uma resposta baseada GigaSpaces que atende aos seus critérios, dependendo exatamente o que você quer dizer em critérios 3. Eu trabalho com GigaSpaces de .Net, não Java:

Crie uma classe de travamento com uma propriedade SpaceID + SpaceRouting Iding o que está bloqueado e uma propriedade DataMember bool Desbloqueado:

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()
    {
    }
}

Você vai usar tempo de concessão GigaSpaces' para o desbloqueio depois de um certo tempo esgotado. Isso fará com que GigaSpaces para remover objetos IdLockTrans a partir do espaço automaticamente depois de terem sido ocioso para o tempo limite período. A falta de um IdLockTrans para um ID significa que o ID é desbloqueado.

Sua classe armário vai definir e inicializar esses membros da 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.");
        }
    }

Outras dicas

A implementação Net é muito próximo a sair existente do bloqueio caixa / API desbloqueio fornecido com a API Java. Vejo: http://www.gigaspaces.com/docs/JavaDoc8 0,0 / org / openspaces / core / DefaultGigaMap.html

Você pode encontrei o código fonte para esta classe Java como parte do arquivo gs-openspaces-src.zip fornecido com o produto. Tendo o mesmo com GigaSpaces .Net API deve ser straightfwd.

No caso de você ainda está procurando, dê uma olhada Apache Zookeeper :

ZooKeeper é um serviço centralizado para manter as informações de configuração, nomeando, proporcionando sincronização distribuída, e prestação de serviços do grupo. Todos esses tipos de serviços são utilizados de alguma forma ou de outra por aplicações distribuídas.

A documentação Zookeeper fornece exemplos de como construir um serviço de bloqueio no topo do Zookeeper.

Use mysql para bloquear uma chave única é muito simples.

Assunção 1:

Você usa transação e seu nível de isolamento é lido comprometido.

Hipótese 2: Você trancá-lo processando fio por uma chave única, e liberá-lo quando a sua transação confirmada.

Em seguida, você pode usar este sql como distribuir lock:

Inserir em distributed_lock (key) valores (# {key}) Tecla ON DUPLICATE KEY update = chave;

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top