As estratégias de bloqueio incluem pessimista, otimista e
nenhum. Para escolher uma estratégia de bloqueio, é necessário
considerar questões como a porcentagem de cada tipo de operações que
você tem, se você utiliza um utilitário de carga, entre outras.
Os bloqueios são limitados pelas transações.
É possível especificar as seguintes configurações de bloqueio:
- Ausência de bloqueio: Executar sem a configuração de bloqueio é a opção
mais rápida. Se estiver utilizando dados de leitura, você talvez não precise do bloqueio.
- Bloqueio pessimistic: Adquire bloqueios em entrada e, em seguida, contém o
bloqueio até o momento do commit. Essa estratégia de bloqueio
fornece boa consistência à custa do rendimento.
- Bloqueio optimistic: Obtém uma imagem anterior de cada registro
que a transação acessa e compara a imagem com os valores de entrada atuais
quando ocorre o commit da transação. Se os valores de entrada forem alterados,
a transação será recuperada. Nenhum bloqueio será retido até o momento da confirmação.
Esta estratégia de bloqueio fornece melhor simultaneidade do que a estratégia
pessimista, no risco da transação sendo recuperada e no custo da memória
de criar a cópia extra da entrada.
Configure a estratégia de bloqueio no BackingMap. Não é possível alterar a
estratégia de bloqueio para cada transação. A seguir há um exemplo de fragmento XML que
mostra como configurar o modo de bloqueio em um mapa utilizando o arquivo XML, assumindo
que
cc é o espaço de nomes para o espaço de nomes
objectgrid/config.
<cc:backingMap name="RuntimeLifespan" lockStrategy="PESSIMISTIC" />
Bloqueio Pessimista
Use
a estratégia de bloqueio pessimista para ler e gravar mapas quando outras
estratégias de bloqueio não foram possíveis. Quando um mapa do
ObjectGrid map é configurado para
utilizar a estratégia de bloqueio pessimista, um bloqueio de transação pessimista para uma entrada de mapa é obtido quando uma transação primeiro obtém a entrada do BackingMap. O bloqueio pessimistic
fica retido até que o aplicativo conclua a transação. Geralmente, a
estratégia de bloqueio pessimistic é utilizada nas seguintes situações:
- Quando o BackingMap é configurado com ou sem um utilitário de carga e as informações
de controle de versões não estão disponíveis.
- Quando o BackingMap é utilizado diretamente por um aplicativo que precisa
de ajuda do eXtreme Scale para controle
de simultaneidade.
- Quando as informações de controle de versões estão disponíveis, mas as transações de atualização colidem frequentemente nas entradas de suporte, resultando em falhas de atualização otimistas.
Como a estratégia de bloqueio pessimista tem o maior impacto no desempenho e escalabilidade,
esta estratégia deve ser utilizada apenas para ler e gravar mapas quando outras
estratégias de bloqueio não são viáveis.
Por exemplo, essas situações incluem quando ocorrem
falhas de atualização otimista com frequência ou quando a recuperação
da falha otimista é difícil para um aplicativo manipular.
Bloqueio Otimista
A
estratégia de bloqueio otimista assume que nenhuma transação em execução simultânea
pode tentar atualizar a mesma entrada de mapa. Devido a esta convicção, o modo de bloqueio não precisa ser retido
pelo ciclo de vida da transação porque é improvável que mais de uma transação
possa atualizar a entrada de mapa simultaneamente. A estratégia de
bloqueio optimistic geralmente é utilizada nas seguintes situações:
- Quando um BackingMap é configurado com ou sem um utilitário de
carga e as informações de controle de versões estão disponíveis.
- Quando um BackingMap possui em sua maior parte, transações que executam
operações de leitura.
As operações insert, update ou remove nas entradas de mapa não
ocorrem com frequência no BackingMap.
- Quando um BackingMap é inserido, atualizado ou removido mais frequentemente
do que é lido, mas as transações raramente colidem na mesma entrada do mapa.
Como a estratégia de bloqueio pessimistic, o métodos na interface ObjectMap
determinam como o
eXtreme Scale automaticamente
tenta adquirir um modo de bloqueio para a entrada de mapa que está sendo
acessada.
Entretanto, existem as seguintes diferenças entre as estratégias pessimistic
e optimistic:
- Como a estratégia de bloqueio pessimistic, um modo de bloqueio S é
adquirido pelos métodos get e getAll
quando o método é chamado. No entanto, com o bloqueio optimistic, o modo de
bloqueio S não fica retido até que a transação seja concluída. Em vez disso,
o modo de bloqueio S é liberado antes de o método retornar ao aplicativo.
O
propósito de adquirir o modo de bloqueio é para que o
eXtreme Scale possa garantir que apenas
dados com commit de outras transações fiquem visíveis para a transação
atual.
Após o eXtreme Scale ter verificado
que ocorreu commit nos dados, o modo de bloqueio S é liberado. No momento
do commit, uma verificação de versão optimistic é executada para garantir
que nenhuma outra transação tenha alterado a entrada do mapa após a transação
atual ter liberado seu modo de bloqueio S. Se uma entrada não for procurada
a partir do mapa antes de ser atualizada, invalidada ou excluída, o tempo de
execução do eXtreme Scale implicitamente
procura a entrada a partir do mapa. Esta operação get implícita
é desempenhada para obter o valor atual no momento em que foi solicitada
a modificação da entrada.
- Diferente da estratégia de bloqueio pessimista, os métodos
getForUpdate e getAllForUpdate são
tratados exatamente como os métodos get e getAll quando a
estratégia de bloqueio otimista é utilizada. Ou seja, um modo de bloqueio S é adquirido
no início do método e o modo de bloqueio S é liberado antes de retornar
para o aplicativo.
Todos os outros métodos ObjectMap são
tratados exatamente como são tratados para a estratégia de bloqueio pessimistic.
Ou seja, quando o método commit é chamado,
um modo de bloqueio X é obtido para qualquer entrada do mapa que tenha sido inserida, atualizada, removida,
tocada ou invalidada e o modo de bloqueio X é retido até que a transação tenha concluído
o processamento de consolidação.
A estratégia de bloqueio optimistic assume que nenhuma transação
em execução simultânea tenta atualizar a mesma entrada de mapa. Devido a
esta suposição, o modo de bloqueio não precisa ser mantido pela duração
da transação porque é improvável que mais de uma transação possa atualizar
a entrada de mapa simultaneamente.
Entretanto, como um modo de bloqueio não foi mantido, outra transação
simultânea poderia potencialmente atualizar a entrada do mapa após a
transação atual ter liberado seu modo de bloqueio S.
Para tratar
esta possibilidade, o eXtreme Scale obtém um bloqueio X no momento do commit e executa uma verificação de
versão optimistic para verificar se nenhuma outra transação alterou a
entrada do mapa após a transação atual ter lido a entrada do mapa a partir
do BackingMap. Se outra transação alterar a entrada do mapa, a verificação
de versão falhará e ocorrerá uma exceção OptimisticCollisionException. Esta exceção força a transação atual a ser retrocedida e o aplicativo deve
tentar novamente a transação inteira. A estratégia de bloqueio optimistic é muito útil quando um mapa é lido em sua maior parte e é improvável
que ocorram atualizações na mesma entrada do mapa.
Ausência de Bloqueio
Quando um BackingMap
é configurado para usar nenhuma estratégia de bloqueio, nenhum bloqueio de transação
para uma entrada de mapa é obtido.
Não utilizar
uma estratégia de bloqueio é útil quando um aplicativo é um gerenciador de
persistência, como um contêiner Enterprise JavaBeans
(EJB) ou quando um aplicativo utiliza Hibernate para obter dados persistentes. Neste
cenário, o BackingMap é configurado sem um utilitário de carga e o gerenciador de persistência
utiliza o BackingMap como um cache de dados. Neste cenário, o gerenciador de persistência
fornece controle de simultaneidade entre transações que estão acessando as mesmas entradas
de Mapa.
O WebSphere eXtreme
Scale não precisa obter nenhum
bloqueio de transação para o propósito de controle de simultaneidade. Essa situação presume que o gerenciador de persistência não libera os bloqueios da transação antes de atualizar o mapa ObjectGrid com as alterações confirmadas. Se o gerenciador de persistência libera seus bloqueios, então uma estratégia
de bloqueio pessimistic ou optimistic deve ser utilizada. Por exemplo, suponha que o gerenciador de persistência de um contêiner EJB esteja atualizando o mapa do ObjectGrid com dados que foram confirmados na transação gerenciada por contêiner de EJB.
Se a atualização do mapa do
ObjectGrid ocorrer antes dos bloqueios
de transação do gerenciador de persistência serem liberados, então é possível
não utilizar nenhuma estratégia de bloqueio. Se o mapa do
ObjectGrid ocorrer após os
bloqueios de transação do gerenciador de persistência serem liberados,
será necessário utilizar a estratégia de bloqueio otimista ou
pessimista.
Outro cenário onde a ausência de estratégia de
bloqueio pode ser utilizada é quando o aplicativo utiliza um
BackingMap diretamente e um Utilitário de Carga é configurado para
o mapa. Neste cenário, o utilitário de carga utiliza o suporte de controle de
simultaneidade que é fornecido por um Relational Database Management
System (RDBMS) utilizando Java Database
Connectivity (JDBC) ou Hibernate para acessar dados em um banco de dados
relacional. A implementação do utilitário de carga pode utilizar uma abordagem optimistic
ou pessimistic. Um utilitário de carga que utiliza um bloqueio optimistic ou
uma abordagem de controle de versões ajuda a obter a maior quantidade de
simultaneidade e desempenho. Para obter mais informações sobre como implementar uma abordagem de bloqueio otimista, consulte a seção OptimisticCallback em Configurando Carregadores de Banco de Dados. Se estiver usando um utilitário de carga que usa suporte de bloqueio pessimistic de um backend subjacente, é possível querer usar o parâmetro forUpdate que é transmitido no método get da interface do utilitário de carga. Configure este parâmetro como true se o método getForUpdate
da interface ObjectMap foi utilizado pelo aplicativo para obter os dados. O utilitário de carga pode utilizar esse parâmetro para determinar se solicitará um
bloqueio atualizável na linha que está sendo lida. Por exemplo, o DB2 obtém um bloqueio atualizável quando uma instrução select SQL contém uma cláusula FOR
UPDATE. Esta
abordagem oferece a mesma prevenção de conflito que está descrita
em Bloqueio Pessimista.
Para obter mais informações,
consulte o Bloqueios ou o Gerenciador de Bloqueio.