Por que o bloqueio otimista é mais rápido que o bloqueio pessimista?

9

Ambas as formas de bloqueio fazem com que um processo aguarde uma cópia correta do registro, se ele estiver sendo usado atualmente por outro processo. Com o bloqueio pessimista, o mecanismo de bloqueio vem do próprio banco de dados (um objeto de bloqueio nativo), enquanto que com o bloqueio otimista, o mecanismo de bloqueio é uma forma de versão de linha como um carimbo de data e hora para verificar se um registro está "obsoleto" ou não.

Mas ambos causam um segundo processo travar. Então, pergunto: por que o bloqueio otimista geralmente é considerado mais rápido / superior do que o bloqueio pessimista? E há casos de uso em que o pessimista é preferível ao otimista? Desde já, obrigado!

Mara
fonte
5
Existe uma explicação muito curta na nomeação. O bloqueio otimista funciona bem quando a chance de um bloqueio conflitante é baixa. Estamos otimistas sobre a interação de vários processos. O bloqueio pessimista funciona bem quando a chance de um bloqueio conflitante é alta. Somos pessimistas quanto à interação de múltiplos processos. Ambos terão um desempenho subótimo, onde seu oposto seria mais apropriado.
Mark Storey-Smith
o bloqueio otimista pode ou não ser mais rápido que o bloqueio pessimista, dependendo da sua carga de trabalho.
AK

Respostas:

8

Duplicar pergunta de:

/programming/129329/optimistic-vs-pessimistic-locking

Copie / cole a resposta no link acima:

O bloqueio otimista é uma estratégia em que você lê um registro, anota o número da versão e verifica se a versão não foi alterada antes de gravar o registro. Ao gravar o registro, você filtra a atualização na versão para garantir que ela seja atômica. (ou seja, não foi atualizado entre quando você verifica a versão e grava o registro no disco) e atualiza a versão em uma ocorrência.

Se o registro estiver sujo (ou seja, versão diferente da sua), você abortará a transação e o usuário poderá reiniciá-la.

Essa estratégia é mais aplicável a sistemas de alto volume e arquiteturas de três camadas em que você não mantém necessariamente uma conexão com o banco de dados para sua sessão. Nessa situação, o cliente não pode realmente manter bloqueios de banco de dados, pois as conexões são obtidas de um pool e você pode não estar usando a mesma conexão de um acesso para o próximo.

Bloqueio pessimista é quando você bloqueia o registro para seu uso exclusivo até terminar com ele. Ele tem uma integridade muito melhor do que o bloqueio otimista, mas exige que você tenha cuidado com o design do aplicativo para evitar conflitos. Para usar o bloqueio pessimista, você precisa de uma conexão direta com o banco de dados (como seria o caso em um aplicativo de servidor cliente de duas camadas) ou um ID de transação disponível externamente que possa ser usado independentemente da conexão.

No último caso, você abre a transação com o TxID e reconecta usando esse ID. O DBMS mantém os bloqueios e permite que você selecione a sessão novamente através do TxID. É assim que as transações distribuídas usando protocolos de confirmação de duas fases (como transações XA ou COM +) funcionam.

Editar (Adicionando mais informações para resolver a questão de desempenho):

Em termos de desempenho, depende do seu ambiente. Considere os seguintes fatores para decidir:

você achará que otimista será melhor devido à concorrência na maioria das situações. Dependendo do RDBMS e do ambiente, esse desempenho pode ter um desempenho menor ou menor. Normalmente, com o bloqueio otimista, você encontrará que o valor precisa ser versionado em linha em algum lugar.

Com o MS SQL Server, por exemplo, ele é movido para o TempDB e algo entre 12 e 14 bytes é anexado no final da coluna. Ativar o bloqueio otimista com um nível de isolamento, como Isolamento de instantâneo, pode causar fragmentação e seu fator de preenchimento precisará ser ajustado, pois as linhas agora têm dados adicionais no final, o que pode fazer com que uma página quase cheia cause uma divisão de página, o que diminuirá o seu desempenho. Se o seu TempDB estiver sub otimizado, isso não será tão rápido.

Então eu acho que uma lista de verificação é:

  • -Você possui IO / recursos suficientes para lidar com a forma de controle de versão de linha? Caso contrário, você está adicionando sobrecarga. Nesse caso, se você estiver lendo os dados frequentemente enquanto os bloqueia para gravações, notará uma boa melhoria na simultaneidade entre leituras e gravações (embora as gravações ainda bloqueiem gravações, as leituras não bloqueiem mais as gravações e vice-versa)
  • -O seu código é suscetível a conflitos ou você experimenta o bloqueio? Se você não estiver enfrentando bloqueios longos ou muitos bloqueios, a sobrecarga adicional do bloqueio otimista não tornaria as coisas mais rápidas, é claro, na maioria dos casos, estamos falando de milissegundos aqui.
  • -Se o seu banco de dados for grande (ou em hardware muito limitado) e as páginas de dados estiverem quase cheias, dependendo do RDBMS, você poderá causar grandes divisões de página e fragmentação de dados, portanto, pense em reindexar depois de ativá-lo.

Esses são meus pensamentos sobre o assunto, abertos a ouvir mais da comunidade.

Ali Razeghi
fonte
Obrigado, Ali Razeghi (+1) - Eu acho que o dba.se é um local mais apropriado para esta pergunta. Além disso, embora seja uma resposta excelente, ela não responde à minha pergunta sobre desempenho (quando uma é mais rápida que a outra). Obrigado novamente!
Mara
Oi Mara, esse é um bom argumento. Eu ampliei a resposta. Obrigado.
Ali Razeghi
11

Você entende mal o bloqueio otimista.

O bloqueio otimista não faz com que as transações esperem uma pela outra.

O bloqueio otimista possivelmente faz com que uma transação falhe, mas o faz sem que nenhum "bloqueio" tenha sido realizado. E se uma transação falhar devido ao bloqueio otimista, é necessário que o usuário inicie tudo de novo. A palavra "otimista" deriva exatamente da expectativa de que a condição que causa falha nas transações por esse mesmo motivo ocorra apenas de maneira muito excepcional. O bloqueio "otimista" é a abordagem que diz: "Eu não pegarei bloqueios reais, porque espero que eles não sejam necessários de qualquer maneira. Se acontecer que eu estava errado sobre isso, aceitarei a falha inevitável".

Erwin Smout
fonte
1

O bloqueio otimista geralmente é mais rápido porque, na verdade, não há bloqueio do ponto de vista do banco de dados. Cabe inteiramente à aplicação respeitar a coluna da versão (ou pseudo-coluna, como ora_rowscn) ou não. Normalmente, você tem muitos aplicativos conectados ao mesmo banco de dados, para que o db se torne um recurso compartilhado e, se travar, todos os clientes serão afetados.

Com a estratégia de bloqueio otimista, o 'travamento' acontece no lado do cliente e não afeta os outros.

No entanto, se um registro for atualizado com freqüência, você poderá relê-lo muitas vezes (no caso de bloqueio otimista), derrotando os benefícios da estratégia otimista.

Eu não concordaria sobre a superioridade de qualquer uma das abordagens; ambos podem ser mal utilizados. O pessimista é mais suscetível a erros apenas porque é mais perigoso: o bloqueio ocorre no nível de banco de dados, depende do RDMS; talvez você não tenha controle sobre o que está bloqueado (escalação de bloqueios), é necessário cuidar da ordem de bloqueio manualmente.

a1ex07
fonte
ponto interessante a1ex07, o bloqueio otimista ainda inclui o bloqueio, pois as gravações sempre bloqueiam outras gravações, correto?
Ali Razeghi
Não, não faz. É por isso que é "mais rápido".
Erwin Smout 02/03
Esse pode ser o caso do Oracle, mas do MS SQL Server, como usa o nível de isolamento 'leitura confirmada' por padrão, o bloqueio otimista permitirá que os segmentos de leitores e gravadores trabalhem simultaneamente, mas as gravações bloquearão as gravações até que o segmento de bloqueio seja confirmado.
Ali Razeghi
@ Ali Razeghi: Não tenho certeza se sigo o seu ponto. No SQLServer com gravadores confirmados de leitura, bloqueia os leitores por padrão, a menos que o `READ_COMMITTED_SNAPSHOT` esteja ativado. O bloqueio otimista não é um bloqueio no recurso db (linha / página / tabela), mas sim algum tipo de acordo entre todos os aplicativos que usam o banco de dados para não atualizar o registro se a versão não corresponder ao esperado.
precisa saber é
11
@Eamon Nerbonne: Eu disse sobre 'escritores não bloqueiam leitores' ... Onde você viu eu mencionei algo sobre "escritores bloqueiam / não bloqueiam escritores"?
a1ex07
0

O bloqueio otimista pressupõe que transações simultâneas possam ser concluídas sem se afetar. Portanto, o bloqueio otimista é mais rápido porque nenhum bloqueio é imposto durante as transações. É a prevenção de causar problemas de simultaneidade e não curar. A transação apenas verifica (três maneiras Conjuntos de dados, Tipo de dados Timestamp, Verificar valor antigo e novo) os dados que nenhuma outra transação modificou. Em caso de modificação, a transação é revertida.

O bloqueio pessimista pressupõe que as transações simultâneas entrem em conflito entre si; portanto, exige bloqueio; isso é feito especificando o nível ISOLATION (leitura não confirmada, leitura confirmada, leitura repetida e serializável) do gerenciamento de transações. Os bloqueios servem para proteger recursos ou objetos compartilhados (tabelas, linhas de dados, blocos de dados, itens em cache, conexões e sistemas inteiros). Temos muitos tipos de bloqueios como bloqueios compartilhados, bloqueio de atualização, bloqueio interno, bloqueios exclusivos, bloqueios de transação, bloqueios de DML, bloqueios de esquema e bloqueios de recuperação de backup.

para ter mais ideia

Premraj
fonte
-3

É falso dizer que o bloqueio pessimista é mais lento que otimista ou dizer que otimista é mais rápido. Uma consulta clássica para demonstrar essa maneira inadequada de pensar é fazer uma agregação nos diferentes RDBMS, como:

SELECT COUNT(*) FROM atable

Você verá que, no RDBMS que suporta abordagem nativamente otimista, o tempo gasto por essa consulta é muito mais significativo do que aqueles que possuem um bloqueio nativamente pessimista

Por exemplo, no meu PC, a mesma consulta leva 27 ms no SQL Server e 109 no PostGreSQL ...

A sobrecarga extra necessária na leitura de versões mortas das linhas MVCC e não conta os registros de fantasmas no agregado adiciona um custo extra que os pessimistas não têm!

user7370003
fonte
4
A abordagem de controle de simultaneidade do DBMS é ortogonal ao bloqueio otimista / pessimista, e a comparação dos tempos de execução da consulta em dois DBMS diferentes é enganosa.
Mustaccio
como o SQL Server é capaz de executar os dois modos de bloqueio, você pode comparar isso facilmente, criando um verdadeiro marco na abordagem de simultaneidade do usuário.
User7370003 27/03