¿Cómo gestionar 2 métodos DAO en una sola transacción?

12

En una entrevista, alguien me preguntó: ¿Cómo gestionamos 2 métodos transaccionales / dao en una sola transacción? Capacidades deseadas:

  1. Si alguno de ellos falla, necesitamos revertir ambos métodos.
  2. Ambos métodos pueden llamarse unidos por separado con una sola transacción.
  3. La gestión debe estar en la capa DAO, no en la capa de servicio.

Creo: la pregunta se refiere a la gestión de transacciones de primavera.

Satish Pandey
fuente

Respuestas:

12

En primer lugar, la gestión de transacciones debe realizarse en la capa de servicio, no en la capa DAO, ya que eso generaría una gran sobrecarga de rendimiento (para tratar el nivel de aislamiento de transacción y la propagación adecuados en cada método diferente). Además, el alcance de una unidad de trabajo proviene de la capa de servicio en lugar de la capa de acceso a datos: imagine realizar un proceso de negocio que necesita tratar con 2 o más DAO.

Hay mucha discusión en Internet que apunta en esa dirección como aquí , aquí y aquí .

De todos modos, dado que es una entrevista, aceptemos la pregunta tal como está. Desde mi punto de vista, estaría utilizando la @Transactionalanotación (o la configuración XML) en ambos métodos y con una propagación de transacciones con REQUIREDvalor. De esa manera, cuando se invoque cualquiera de esos métodos y si no existe una transacción previa, se creará una nueva transacción:

@Transactional
class MyDAO {

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

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

}
Alonso Dominguez
fuente
¿Significa foo()y bar()comparte la misma transacción y si 1 falla, otro 1 también retrocederá? ¿Me puede dar alguna aclaración?
Satish Pandey
bueno, cada método declara su propia unidad de trabajo: tx se confirmará al final de cada método y si alguno de ellos arroja una excepción, se revertirá.
Alonso Dominguez
entonces necesitamos agregar el @Transactional(propagation = REQUIRED)método de capa DAO para la propagación y la @Transactionalcapa de servicio, pero si pongo la @Transactionalcapa de servicio solo en lugar de poner en la capa DAO, ¿cuál es la diferencia?
atish shimpi
propagation = REQUIREDes el valor predeterminado para la propagación de anotaciones transaccionales, por lo que no es necesario escribirlo.
Daniel Higueras
2

Ignorando la primavera y los marcos en mi respuesta ... solo la idea básica de usar parámetros de función. Estoy seguro de que el concepto podría aplicarse dentro de [insertar marco aquí].

Debería manejar el commit / rollback fuera de los 2 métodos DAO. Los 2 métodos tendrían que tomar la transacción / conexión 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();  }
}
mike30
fuente
1 pregunta: por qué estamos pasando Tran tcomo parámetro con ambos métodos. ¿Puedes dar alguna explicación?
Satish Pandey
@Satish, porque en la pregunta (ítem # 1 y # 2), los métodos DAO necesitan tener la flexibilidad para ser llamados de manera independiente y dependiente. Si confirma dentro de method1 con una transacción de ámbito local, entonces no podría revertir si algo salió mal en method2 ya que ya ha confirmado method1 antes de que se invocara method2.
mike30
0

Existe la posibilidad de que dos métodos funcionen de forma independiente y al mismo tiempo que se ejecute en una misma transacción. Por lo tanto, debemos usar Propagación requerida. Si la transacción tiene que ejecutarse en la misma transacción, usará la primera transacción; de lo contrario, se creará una nueva transacción si se invoca de forma independiente. Corrígeme si estoy equivocado.

M. Anil Kumar
fuente
¿Puedes dar un ejemplo por favor?
Jay Elston