es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Puede un método @Transactional llamar a otro método @Transactional sin suspenderse?

Tengo el método A y el método B en diferentes clases. Ambos están anotados con @Transactional. El método A llama a B. ¿Existe alguna solución para llamar a B en una transacción diferente sin suspender la transacción de A? Propagation.REQUIRES_NEW en B ofrece la posibilidad de crear siempre una nueva transacción cuando se llama, pero suspende la transacción del llamador.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una solución para llamar al método B en una transacción diferente sin suspender la transacción del método A.
    Una forma de lograr esto es utilizando la Programación Orientada a Aspectos (AOP) con Spring AOP.
    Podemos definir un aspecto separado para el método B con la propagación Propagation.REQUIRES_NEW y luego llamar al método B utilizando este aspecto en lugar de la anotación original @Transactional. Esto creará una nueva transacción para el método B sin suspender la transacción del método A.

    Por ejemplo, podríamos definir el siguiente aspecto:

    @Component
    @Aspect
    public class MyAspect {
    
        @Around("@annotation(org.springframework.transaction.annotation.Transactional) && execution(* package.to.methodB(..))")
        public Object methodBWithNewTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
    
            TransactionStatus status = transactionManager.getTransaction(def);
            try {
                // Ejecutar el método B con una nueva transacción
                Object result = joinPoint.proceed();
                transactionManager.commit(status);
                return result;
            } catch (Throwable ex) {
                transactionManager.rollback(status);
                throw ex;
            }
        }
    }
    

    Luego, podemos llamar al método B utilizando el nombre del aspecto:

    @Autowired
    private MethodBClass methodBClass;
    
    @Transactional
    public void methodA() {
        // Realizar algunas tareas transaccionales
    
        // Llamar al método B con una nueva transacción
        methodBClass.methodBWithNewTransaction();
    }
    

Comments are closed.