Como funciona o Terracota nesta situação?
-
03-07-2019 - |
Pergunta
Então digamos que eu tenho um N array de servidores de tamanho configurado da seguinte forma:
Eu tenho um JavaBean/POJO simples:
package example;
public class Person {
private OtherObject obj;
public void setObj(OtherObject theObj) {
synchronized (this) {
obj = theObj;
}
}
public OtherObject getObj() {
synchronized (this) {
return obj;
}
}
}
Agora, se um dos Clientes chama Person.setObj(OtherObject) em um Objeto Person na raiz do TC (estrutura de dados), é o bloco sincronizado (em Person.setObj(OtherObject)) nesse cliente mantinha:
1) Até tudo N dos Servidores do N matriz de servidores de tamanho grande foi sincronizada/atualizada com esse atributo Person.obj?
ou
2) Até que o servidor "ativo" seja sincronizado com o atributo Person.obj atualizado?Depois o outro (N-1) os servidores do array estão sincronizados tanto quanto possível?
ou
3) Algum outro método que estou procurando?
Solução
A resposta não é realmente 1 ou 2. Os objetos são listrados nos grupos de espelhos do servidor. Na primeira vez em que esse campo é definido, uma transação é criada e esse grupo de espelho escolhido para essa primeira transação "possuirá" o objeto depois disso.
Com relação a 1 e 2, nem todos os grupos de servidores ativos precisam ser atualizados, para que não haja necessidade de aguardar nenhuma dessas condições.
Você pode encontrar mais informações na documentação da Terracota sobre a configuração da matriz do Terracotta Server:
Do ponto de vista de travamento, a trava em cluster nesse objeto de pessoa seria mantida (exclusão mútua em todo o cluster) enquanto executava a modificação do objeto. O escopo do bloco sincronizado forma a transação mencionada acima. No método getObj (), você pode configurar isso como um bloqueio de leitura que permitiria vários leitores simultâneos em todo o cluster.
Outras dicas
Suponha que todo mundo tenha uma referência ao seu objeto e possa tocá -lo enquanto/antes/depois de fazer. Assim, a solução seria adicionar bloqueios e
- Obtenha bloqueio
- modificar o objeto
- Libere o bloqueio
E isso é exatamente o que sincronizado faz ... isso cria uma fila e o Método sincronizado Não pode ser chamado mais de uma vez ... mas o objeto subjacente pode ser tocado se for referenciado em algum lugar.
Vejo:
Não estou familiarizado com a implementação deles (terracota), mas do ponto de vista do JMM, deve faça um bloqueio em todo o cluster.Contudo, este exemplo é muito simples;apenas uma mudança de uma referência, e isso pode fazer com que ela seja convertida em algo mais parecido com uma gravação volátil e evite completamente o bloqueio.
Mas, se você fizer coisas não triviais em seu bloco sincronizado, então eu assumiria que o TC pessimistamente adota um bloqueio em todo o cluser no início do bloco sincronizado.Caso contrário, estariam em desacordo com as especificações do JMM.Como eu entendo.
Em outras palavras, sua opção nº 1.Portanto, tome cuidado com o que você compartilha no cluster e use objetos imutáveis e estruturas de dados java.util.concurrent.* quando puder - o último está recebendo um amor intrínseco especial no TC.