簡體   English   中英

如何在Spring Boot中管理事務

[英]How to manage transactions in spring boot

我有一個spring boot應用程序,並使用了駱駝,我讀了一個文件,然后嘗試插入數據庫中,一切正常,唯一的問題是我嘗試使用@transactionaltransactionTemplate在發生錯誤時進行回滾發生但不會進行回滾,

使用@transactional我將@EnableTransactionManagement(proxyTargetClass=true)添加到我的SpringBootApplication中,並在我的課程中添加@Transactional(rollbackFor = Exception.class)

這些是我的課程:

@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
    }
}

有了transactioTemplate,我的課就這樣結束了:

@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();
            }
        }
       });
    }
}

我有什么遺漏嗎?,有人可以幫我解決這個問題嗎?

提前致謝

您處於駱駝環境中,Spring-boot可能難以正常工作。 您可以嘗試在spring服務中進行事務操作,然后將其注入處理器中,然后在服務方法上添加@Transaction並從處理器中調用它。

最后,我注意到我需要為數據源指定DataSourceTransactionManager,我有一個帶有@Configuration批注的類,並且可以在其中創建倍數數據源,所以我的類如下所示:

@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);
    }

}

該文檔提到,注釋@EnableTransactionManagement需要在SpringBootApplication類上添加,但這不是必需的,它需要在配置類上添加,因此我的類最終如下所示:

@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());
    }

}

通過這種配置,我只需要向類中添加@transactional批注,例如@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()));
    }

}

希望這可以幫助其他人:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM