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:
Postar um comentário