为什么@Transactional + spring数据jdbc + Sybase不回滚?

时间:2018-06-14 23:03:16

标签: java spring-boot sybase spring-transactions transactional

方案如下:

我在使用@transactional注释的服务层中有一个名为insert()的方法,其中有四个其他方法,第一个方法generateCorrelativeCode位于另一个服务中,该服务也使用带有选项REQUIRED_NEW的@Transactional注释。 因此,当我强制在segmentDAO.save中抛出一个RunTimeException以测试回滚但没有发生任何事情时,我的意思是插入不会被还原,即使在日志中打印它会进行回滚。

我做了很多研究但我在程序中找不到错误,因为没有打印出任何错误。

主要方法的代码是这样的:

@Transactional
public void insert(InvoiceRQ invoiceRQ) {

    ItemGroup itemGroup = itemRepository.findOne(invoiceRQ.getId());
    final String gds = itemGroup.getItems().get(0).getGds();
    String correlative = correlativeService.generateCorrelativeCode(gds);

    for (Item item : itemGroup.getItems()) {

        Payment payment = saleTransfer.buildPayment(item, correlative);
        long payId = paymentDAO.save(payment);

        Invoice invoice = saleTransfer.buildInvoice(item, payId, correlative, gds);
        invoiceDAO.save(invoice);

        Segment segment = new Segment();
        segmentDAO.save(segment);
    }
}

generateCorrelativeCode方法的代码:

@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.REPEATABLE_READ)
public String generateCorrelativeCode(String gdsId) {

    CorrelativeInvoice correlativeInvoice = correlativeInvoiceDAO.findOneBygdsId(gdsId);
    correlativeInvoice.generateNextCode();
    correlativeInvoiceDAO.updateCurrentCode(correlativeInvoice.getCurrentCode(), gdsId);
    return correlativeInvoice.getCurrentCode();
}

以下是我故意抛出以生成回滚的异常代码:

public int save(Segment segment) {

    String query = "INSERT...";

    int affectedRows = 0;

    if (affectedRows == 0) {
        throw new RuntimeException("Test");
    }

    try {
        affectedRows = namedParameterJdbcTemplate.update(query, new BeanPropertySqlParameterSource(segment));
    } catch (Exception e) {
        LOGGER.error("Error on save Segment", e);
    }
    return affectedRows;
}

这是日志:

  

[TRACE] 2018-06-14 17:41:40 TRACE TransactionInterceptor completeTransactionAfterThrowing(TransactionAspectSupport.java:531) - 在异常:java.lang之后完成[tech.zdev.senju.domain.SaleService.insert]的事务。 RuntimeException:测试   [TRACE] 2018-06-14 17:41:40 TRACE RuleBasedTransactionAttribute rollbackOn(RuleBasedTransactionAttribute.java:131) - 应用规则来确定事务是否应该在java.lang.RuntimeException上回滚:测试   [TRACE] 2018-06-14 17:41:40 TRACE RuleBasedTransactionAttribute rollbackOn(RuleBasedTransactionAttribute.java:148) - Winning回滚规则为:null   [TRACE] 2018-06-14 17:41:40 TRACE RuleBasedTransactionAttribute rollbackOn(RuleBasedTransactionAttribute.java:153) - 找不到相关的回滚规则:应用默认规则   [DEBUG] 2018-06-14 17:41:40 DEBUG DataSourceTransactionManager processRollback(AbstractPlatformTransactionManager.java:855) - 启动事务回滚   [DEBUG] 2018-06-14 17:41:40 DEBUG DataSourceTransactionManager doRollback(DataSourceTransactionManager.java:325) - 在连接上回滚JDBC事务[ConnectionID:1 ClientConnectionId:7464bae5-ce01-4b93-907e-72be07db5955]   [DEBUG] 2018-06-14 17:41:40 DEBUG DataSourceTransactionManager doCleanupAfterCompletion(DataSourceTransactionManager.java:368) - 事务发布后释放JDBC连接[ConnectionID:1 ClientConnectionId:7464bae5-ce01-4b93-907e-72be07db5955]   [ERROR] 2018-06-14 17:41:40错误ErrorPageFilter forwardToErrorPage(ErrorPageFilter.java:178) - 由于异常[测试]转发到请求[/ invoice]的错误页面    java.lang.RuntimeException:Test

一切看起来都不错,但该方法不会回滚。

注意:在CorrelativeService中,它连接到SQLServer而不是sybase,但即使有回滚也可以。

如果有人可以帮助我,我会非常感激。感谢

0 个答案:

没有答案