方案如下:
我在使用@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,但即使有回滚也可以。
如果有人可以帮助我,我会非常感激。感谢