I have a spring boot application and use camel with it, I read a file and then I try to inserted on my DB, everything is working good the only problem is that I try to use @transactional
or transactionTemplate
to make a rollback when an error occur but it doesn't make the rollback,
With the @transactional
I add to my SpringBootApplication the @EnableTransactionManagement(proxyTargetClass=true)
and in my class I add the @Transactional(rollbackFor = Exception.class)
These are my classes:
@SpringBootApplication
@EnableDiscoveryClient
@EnableTransactionManagement(proxyTargetClass=true)
public class MsArchivo510Application {
public static void main(String[] args) {
SpringApplication.run(MsArchivo510Application.class, args);
}
}
@Service
public class ArchivoBS implements Processor{
@Transactional(rollbackFor = Exception.class)
@Override
public void process(Exchange exchange) throws Exception {
//Here I execute stored procedure and one of them fail
}
}
With the transactioTemplate my class end up like this:
@Service
public class ArchivoBS implements Processor{
@Override
public void process(Exchange exchange) throws Exception {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
//Here I execute stored procedure and one of them fail
} catch (Exception e) {
e.printStackTrace();
status.setRollbackOnly();
}
}
});
}
}
Am I missing something?, Can someone help me with this issue?,
Thanks in advance
At the end I noticed that I need to specify to my data source the DataSourceTransactionManager, I have a class with the annotation @Configuration and there I can create multiples data source, so my class were like this:
@Configuration
public class Configuracion {
@Bean(name = "mysqlNocturno")
@ConfigurationProperties(prefix = "spring.nocturno")
public DataSource mysqlDataSourceNocturno() {
return DataSourceBuilder.create().build();
}
@Bean(name = "jdbcTemplateNocturno")
public JdbcTemplate jdbcTemplateNocturno(@Qualifier("mysqlNocturno") DataSource dsMySQL) {
return new JdbcTemplate(dsMySQL);
}
@Bean(name = "mysqlProduccion")
@Primary
@ConfigurationProperties(prefix = "spring.produccion")
public DataSource mysqlDataSourceProduccion() {
return DataSourceBuilder.create().build();
}
@Bean(name = "jdbcTemplateProduccion")
public JdbcTemplate jdbcTemplateProduccion(@Qualifier("mysqlProduccion") DataSource dsMySQL) {
return new JdbcTemplate(dsMySQL);
}
}
The documentation mention that the annotation @EnableTransactionManagement need to be added on my SpringBootApplication class but that is not necessary, it need to be added on my configuration class, so my class end up like this:
@Configuration
@EnableTransactionManagement
public class Configuracion {
@Bean(name = "mysqlNocturno")
@ConfigurationProperties(prefix = "spring.nocturno")
public DataSource mysqlDataSourceNocturno() {
return DataSourceBuilder.create().build();
}
@Bean(name = "jdbcTemplateNocturno")
public JdbcTemplate jdbcTemplateNocturno(@Qualifier("mysqlNocturno") DataSource dsMySQL) {
return new JdbcTemplate(dsMySQL);
}
@Bean(name = "transactionManagerNocturno")
public PlatformTransactionManager transactionManagerNocturno() {
return new DataSourceTransactionManager(mysqlDataSourceNocturno());
}
@Bean(name = "mysqlProduccion")
@Primary
@ConfigurationProperties(prefix = "spring.produccion")
public DataSource mysqlDataSourceProduccion() {
return DataSourceBuilder.create().build();
}
@Bean(name = "jdbcTemplateProduccion")
public JdbcTemplate jdbcTemplateProduccion(@Qualifier("mysqlProduccion") DataSource dsMySQL) {
return new JdbcTemplate(dsMySQL);
}
@Bean(name = "transactionManagerProduccion")
public PlatformTransactionManager transactionManagerProduccion() {
return new DataSourceTransactionManager(mysqlDataSourceProduccion());
}
}
With this configuration I only need to add the @transactional annotation to my class like @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
@Override
public void altaArchivo(Mensaje objMensaje, ArchivoCarnet objArchivoCarnet, ArchivoCarnetTrailer objArchivoCarnetTrailer, List<ArchivoCarnetDetalle> lstArchivoCarnetDetalle) {
if (objMensaje.getStrCodigo().equals(ArchivoErrorEnum.OPERACION_EXITOSA.getStrCodigo())) {
archivoDAO.altaArchivoCarnet(objArchivoCarnet);
archivoDAO.altaArchivoCarnetTrailer(objArchivoCarnetTrailer);
archivoDAO.altaArchivoCarnetDetalle(lstArchivoCarnetDetalle);
} else {
archivoDAO.altaBitacoraArchivo510(new BitacoraArchivo510(objMensaje, objArchivoCarnet.getStrNombre()));
}
}
Hope this help someone else :)