OTIMIZANDO TRANSACTIONS LENTAS COM O PATTERN SERVICELOCATOR DE EJBS

Olá, dependendo do caso é preciso que bole-se uma solução para otimizar alguma chamada que possa por ventura estar lenta, gerando um processamento maior que o esperado e conseqüentemente correr-se o risco de receber uma excessão de TimeOut, retornada pelo banco de dados e tratada pelo entityManager. Como sempre recomendo aqui, utilize SessionBeans CMP onde o container controlará sempre a persistência à dados. O rollBack nesse caso será feito automaticamente.

Tem-se no caso um SessionBean Stateless onde um procedimento realmente demorado é executado.

public MyBean implements myLocalInterface {
@PersistenceContext
EntityManager em;

public myMethodWithHardLogic(int myParam) {


// your complex logic here (sua lógica complexa aqui)


// old code (este código antigo passará para a classe listada
//abaixo)
for.... {
MyEntity myEntity = em.find(MyEntity.class, myParam);

if (myEntity.myVariable) {
myEntity.setMyType(1);
} else {

if (myOtherCondition) {
myEntity.setMyType(275);
} else {
myEntity.setMyType(32);
}

}

em.merge(myEntity);

for (MyArray myArray : em.getMyArray ) {

em.persist(em.find((MyClassOfMyArray) myArray.get(0)));
}

//... etc etc etc etc etc etc
}
}
}


Onde o otimizador de lookups de acordo com o Pattern usado (Facade, Business Delegate). No caso, seu delegator


public myClassDelagator {

boolean etc;

MyBean myBean;

public myClassDelagator() {
executeMyLookUp();
}

public myClassDelagator(boolean etc) {
executeMyLookUp();
this.etc = etc;
}

ptivate executeMyLookUp() {
myBean = ServiceLocator.getInstance().... etc.... lookup("my_JNDI_NAME");
}


public delegateToInterface() {

// aqui entra a nova lógica, que antes estava dentro do Bean
if (etc) {
myBean.myMethodWithHardLogic(1);
myBean.myMethodWithHardLogic(2);
myBean.myMethodWithHardLogic(275);
} else {
myBean.myMethodWithHardLogic(7);
myBean.myMethodWithHardLogic(12);
myBean.myMethodWithHardLogic(32);
}

}

}


Veja no exemplo acima, se cada chamada myBean.myMethodWithHardLogic(...) demorava 10 segundos, se multiplicares por 3 teremos uma única transação com 30 segundos (quando maior esse número, mais "atolado" de 1 vez só ficará o Banco de dados), mas se particionares os chamadas em 3 vezes, terás apenas uma transação com 10 segundos sendo executada de cada vez.

Cabe lembrar que EJB veio para facilitar, mas não faz milagre, você precisa saber o que esta fazendo, a execução de um método dentro de um SessionBean (Estamos falando de EJB CMP) onde a instância do PersistenceContext esta definida se equivale à abertura de uma conexão, commit, rollBack (se for o caso), fechamento da conexão. Não é porque o framework faz tudo automático que ele tem a obrigação de saber quanto tempo deve demorar cada processo, ou quanto tempo sua transação deve durar. É isso que nos difere do framework, a nossa capacidade de pensar e planejar de forma eficiente de modo a não onerar o banco de dados. Antes de culpar o framework, pense se esta utilizando-o da melhor maneira, nada é tão bom ao ponto de servir para todos os casos possíveis.

Espero poder ter ajudado a quem me dá a honra de seu acesso.

Lembrando que estes exemplos devem ser usados quando a lógica realmente é muito complexa, em casos simples (apenas um insert, update delete, etc etc etc) deixe tudo à cargo do entityManager, ele se vira, e se vira muito bem.

Dúvidas é só comentar.

Um Abraço

Nenhum comentário: