Como gerenciar 2 métodos DAO em uma única transação?


12

Em uma entrevista, alguém me perguntou: como gerenciamos 2 métodos transacionais / dao em uma única transação. Recursos desejados:

  1. Se alguém falhar, precisamos reverter os dois métodos.
  2. Ambos os métodos podem ser chamados separadamente anexados com uma única transação.
  3. O gerenciamento deve estar na camada DAO, não na camada de serviço.

Penso: a questão está relacionada ao gerenciamento de transações da primavera.

Respostas:


12

Primeiro de tudo, o gerenciamento de transações deve ser feito na camada de serviço, e não na camada DAO, pois isso criaria muita sobrecarga de desempenho (para lidar com o nível de isolamento de transação apropriado e a propagação em cada método diferente). Além disso, o escopo de uma unidade de trabalho vem da camada de serviço, e não da camada de acesso a dados: imagine executar um processo de negócios que precise lidar com 2 ou mais DAOs.

Há muita discussão na Internet que aponta nessa direção, como aqui , aqui e aqui .

De qualquer forma, já que é uma entrevista, vamos aceitar a pergunta como ela é. Do meu ponto de vista, você usaria a @Transactionalanotação (ou a configuração XML) nos dois métodos e com uma propagação de transação com REQUIREDvalor. Dessa forma, quando qualquer um desses métodos for chamado e se nenhuma transação anterior existir, uma nova transação será criada:

@Transactional
class MyDAO {

   @Transactional(propagation = REQUIRED)
   public void foo() {
   }

   @Transactional(propagation = REQUIRED)
   public void bar() {
   }

}

Isso significa foo()e bar()compartilha a mesma transação e, se 1 falhar, outro 1 também reverterá? Você pode fornecer algum esclarecimento?
Satish Pandey

bem, cada método declara sua própria unidade de trabalho: tx será confirmado no final de cada método e, se algum deles lançar uma exceção, será revertido.
Alonso Dominguez

portanto, precisamos adicionar o @Transactional(propagation = REQUIRED)método da camada DAO para propagação e @Transactionalcamada de serviço, mas se eu colocar @Transactionalapenas a camada de serviço em vez de colocar a camada DAO, qual é a diferença?
Shimpi Atish

propagation = REQUIREDé o valor padrão para a propagação da anotação transacional; portanto, não é necessário gravá-lo.
Daniel Higueras

2

Ignorando primavera e estruturas na minha resposta ..... apenas a idéia básica de usar parâmetros de função. Tenho certeza de que o conceito pode ser aplicado dentro de [inserir estrutura aqui].

Você precisaria manipular a confirmação / reversão fora dos 2 métodos DAO. Os 2 métodos precisariam tomar a transação / conexão como entrada.

código psuedo:

bool method1(Tran t) { /* stuff */}
bool method2(Tran t) { /* stuff */ }

callingMethod() {
     Tran t = null;
     try {
         t = new Conn().open().startTran();
         if(method1(t) && method2(t))
             t.commit();
         else
             t.rollBaack();
     }
     catch(ex) {  t.rollBack();  }
     finally {  t.closeConn();  }
}

1 pergunta: por que estamos passando Tran tcomo parâmetro com os dois métodos. Você pode fornecer alguma explicação?
Satish Pandey

@ Satish, porque na pergunta (item 1 e 2), os métodos DAO precisam ter flexibilidade para serem chamados de forma independente e dependente. Se você confirmar dentro do método1 com uma transação de escopo local, não poderá reverter se algo der errado no método2, pois você já confirmou o método1 antes de o método2 ser chamado.
Mike30

0

Há uma chance de que dois métodos funcionem independentemente também ao mesmo tempo em que possam ser executados em uma mesma transação. Portanto, precisamos usar Propagation-Required. Se a transação precisar ser executada na mesma transação, ela usará a primeira transação, caso contrário, uma nova transação será criada se invocada de forma independente. Corrija-me se eu estiver errada.


Você pode fornecer um exemplo, por favor?
Jay Elston
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.