Em meu aplicativo, preciso executar um padrão de bloqueio distribuído. Como já temos uma instância do SQL Server para usar, decidimos que seria mais fácil implementar o bloqueio na camada SQL da nossa aplicação web.
Um bloqueio pode ser obtido com base em várias condições, incluindo:
- O tipo de bloqueio solicitado
- Um identificador de aplicativo arbitrário
Para todos os efeitos, trate as duas condições acima como int
tipos de dados.
Nesse padrão, desejamos tratar todos os nossos bloqueios como FIFO, o que acredito que o SERIALIZABLE
nível de isolamento nos dará.
Aqui está como propomos realizar o "bloqueio":
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
IF EXISTS (SELECT 1 FROM locks WHERE LockType = @LockType AND ApplicationIdentifier = @ApplicationIdentifier)
BEGIN
-- Awesome, the lock will be acquired
INSERT INTO locks OUTPUT INSERTED.LockId VALUES (2,3)
END
ELSE
BEGIN
-- Someone already has the lock
SELECT -1
END
SET TRANSACTION ISOLATION LEVEL READ COMITTED
E o "desbloqueio":
DELETE FROM locks WHERE LockId = @LockId
Então minha dúvida é dupla:
- Preciso fazer o "desbloqueio"
SERIALIZABLE
também? - Existem outras abordagens que eu poderia usar/qualquer coisa que eu tenha esquecido?
O SQL Server pode ser 2008/2012
Apesar do nome, o nível de isolamento serializável não garante que as transações sejam executadas sequencialmente ou na ordem recebida. Em vez disso, as transações de garantias serializáveis terão os mesmos efeitos persistentes no banco de dados como se tivessem sido executadas sequencialmente, em alguma ordem indefinida (consulte o link para obter mais detalhes).
Sim. O SQL Server já oferece suporte para bloqueios arbitrários de aplicativos por meio de:
Esses recursos integrados de applock fornecem uma ampla gama de opções e incluem detecção automática de deadlock (embora qualquer reversão de transação necessária seja de responsabilidade do programador). Por exemplo, você pode escolher entre bloqueio com escopo de transação e sessão, em vários modos. Usar esses recursos para implementar o comportamento de que você precisa deve ser bastante direto e certamente mais simples do que criar seu próprio gerenciador de bloqueio resiliente e confiável do zero.