No se encontró el administrador de transacciones predeterminado de Spring al utilizar JmsTransactionManager.
Tengo una aplicación Spring Boot, donde uso JMS con una base de datos. Estoy tratando de configurar JmsTransactionManager
para utilizarlo con el TransactionManager por defecto (para JPA). He definido el bean en el archivo @SpringBootApplication
(eso significa que tiene @Configuration
y @EnableTransactionManagement
):
@Bean(name="jmsTransactionManager")
public JmsTransactionManager jmsTransactionManager(ConnectionFactory connectionFactory) {
JmsTransactionManager jmsTransactionManager = new JmsTransactionManager();
jmsTransactionManager.setConnectionFactory(connectionFactory);
return jmsTransactionManager;
}
Ese es el único bean que configuro manualmente para JMS porque otras configuraciones las realiza automáticamente spring-boot, solo tengo propiedades en application.yaml
, así que asumo que connectionFactory
se autowireará. Y quiero usarlo de la siguiente manera:
@Transactional(transactionManager = "jmsTransactionManager", propagation = Propagation.REQUIRES_NEW)
void do(){
sendJms();
saveDb();
}
@Transactional // utiliza el TransactionManager por defecto de JPA
void sendDb(){
...
}
La lógica es que primero enviaré al JMS y luego guardaré algo en la base de datos, por lo que necesito dos transacciones separadas, pero quiero cerrar la transacción de la base de datos antes de la transacción del JMS. Tal vez no sea correcto realizar llamadas así en esta situación, pero no sé cómo hacerlo de otra manera utilizando la gestión de transacciones declarativa. Y el problema es que cuando estoy definiendo JmsTransactionManagement
, el TransactionManager por defecto, que funciona con la base de datos, deja de funcionar, pero sin JmsTransactionManagement
, las transacciones a la base de datos funcionan correctamente:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'transactionManager' available: No matching TransactionManager bean found for qualifier 'transactionManager' - neither qualifier match nor bean name match!
¿Me estoy perdiendo algo? Tengo spring-data-jpa
en el POM, por lo que el transactionManager
por defecto se configura mediante spring boot, pero no puede encontrarlo, ¿por qué? Desafortunadamente, no encontré la respuesta sobre cómo hacer algo así en StackOverflow.
davy.ai
Parece que estás tratando de utilizar tanto transacciones JMS como JPA en tu aplicación de Spring Boot, pero tienes problemas con la configuración.
Según el mensaje de error que proporcionaste, parece que el TransactionManager por defecto para JPA no está siendo reconocido cuando defines el bean JmsTransactionManager.
Una posible solución para este problema es definir explícitamente el bean TransactionManager por defecto en tu configuración, además de definir el bean JmsTransactionManager.
Aquí tienes un ejemplo de cómo puedes definir ambos beans TransactionManager en la configuración de tu aplicación:
@Configuration
@EnableTransactionManagement
public class AppConfig {
}
En este ejemplo, el bean TransactionManager está definido explícitamente con el nombre “transactionManager” (que coincide con el qualifier por defecto utilizado por Spring Boot para transacciones JPA). Esto debería permitir que Spring identifique correctamente el TransactionManager por defecto al utilizar la anotación @Transactional sin ningún qualifier adicional.
Luego puedes utilizar estos beans TransactionManager en tus métodos de servicio de la siguiente manera:
@Service
public class MyService {
}
En este ejemplo,
doSomething()
está anotado con@Transactional
y especifica explícitamente el TransactionManager “jmsTransactionManager” para la lógica relacionada con JMS. Después de enviar el mensaje JMS, la transacción JMS se confirma utilizando el bean JmsTransactionManager. Luego se inicia una nueva transacción (utilizando el TransactionManager por defecto) para la lógica relacionada con la base de datos, y se confirma después de que el método saveDb() se completa.Ten en cuenta que este enfoque puede no ser el más adecuado para todos los escenarios, y puede que desees considerar otras alternativas como transacciones programáticas o el uso de un TransactionManager diferente que admita varios tipos de recursos.