Pesquisando sobre um erro de duplicação
de dados e problemas com transações no EJB encontrei essa explicação muito
interessante. O atributo REQUIRED_NEW tanto no EJB quanto no Spring podem ter
resultados inesperados e levar a dados corrompidos e inconsistentes. Isso pode
ocorrer devido o fato de ele sempre iniciar uma nova transação quando o método
é chamado, mesmo já existindo uma transação ou não.
Veja o Exemplo:
@Transactional(propagation=Propagation.REQUIRES_NEW)
public long insertTrade(TradeData trade) throws Exception
{
...
}
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void updateAcct(TradeData trade) throws Exception
{
...
}
Nesse caso os 2 métodos são públicos e
estão anotados com REQUIRED_NEW. Quando chamados de forma separada, não há
problema. Porém, se um for usado os dois métodos dentro de uma mesma unidade de
trabalho transacionada, como por exemplo um outro método, isso pode causar inconsistências. Por exemplo, digamos
que dentro do método insertTrade() você chame o método updadeAcct(), se ocorrer
um rolled back depois do chamada do updateAcct(), ele já vai ter efetuado o
commit no banco de dados, sendo desfeito apenas o que pertence ao
insertTrade().
@Transactional(propagation=Propagation.REQUIRES_NEW)
public
long insertTrade(TradeData trade) throws Exception {
em.persist(trade);
updateAcct(trade);
//exception occurs here! Trade
rolled back mas updateAcct(trade) não!
...
}
|
|
Isso acontece porque uma nova transação
é iniciada no método updateAcct() criando uma árvore de transações, e
houve um commit quando ele terminou sua execução, independentemente do que ocorra em outra transação da árvore. Devido a esse
comportamento, o atributo de transação REQUIRES_NEW deve ser usado somente se a
ação do banco de dados no método que está sendo invocado precisa ser salva no
banco de dados independentemente do resultado da transação do topo da
árvore (como uma funcionalidade de auditoria por exemplo).
O ponto principal é sempre usar o
atributo MANDATORY ou REQUIRED vez de REQUIRES_NEW menos que você tenha um motivo
para usá-lo.
Esses são problemas difíceis de serem detectados no momento do desenvolvimento e de testes, pois geralmente ocorrem quando o processamento da aplicação e o acesso ao banco de dados estão muito altos.
Aconselho uma passada por esse outro post que deixo o link logo abaixo também, pois traz um outro problema que pode acarretar em erros semelhantes de inconsistência de dados na aplicação.
Esses são problemas difíceis de serem detectados no momento do desenvolvimento e de testes, pois geralmente ocorrem quando o processamento da aplicação e o acesso ao banco de dados estão muito altos.
Aconselho uma passada por esse outro post que deixo o link logo abaixo também, pois traz um outro problema que pode acarretar em erros semelhantes de inconsistência de dados na aplicação.
Nenhum comentário:
Postar um comentário