猿问

@Transaction 没有在 spring mvc 中回滚

我有基于类的配置,所以用于回滚事务。我使用了 jdbcTemplate。我的 bean 声明如下:


    @Bean

    public DriverManagerDataSource dataSource() {

        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");

        dataSource.setUrl("jdbc:oracle:thin:@192.168.1.5:1521:DCGCDB");

        dataSource.setUsername("PCA_OWNER");

        dataSource.setPassword("PCA_OWNER");


        return dataSource;

    }

<!--for transaction bean-->

@Bean

public PlatformTransactionManager txManager() {

    return new DataSourceTransactionManager(dataSource());

}

因此,在我的服务类中,我声明了 @Transactional 但它不起作用:


@Service

public class ProcessAnexOneServiceImpl implements ProcessAnexOneService {


 @Autowired

 private SelectionCustomOfficeService selectionCustomOfficeService;


 @Autowired

 private LetterDocService letterDocService;


 @Autowired

 private LetterService letterService;


 @Override

 @Transactional

 public void insertProcessAnexOne(ProcessAnexOne processAnexOne, String entryBy) {


  BigDecimal zeroValue = new BigDecimal(0);


  Letter letter = new Letter(processAnexOne.getLetter().getLetterId(), processAnexOne.getLetter().getInout(),

   processAnexOne.getLetter().getInoutNo());

 letter.setEntryBy(entryBy);


  //1st insert Transaction happens here

  BigDecimal letterNo = letterService.insertLetter(letter);

  //1st insert Transaction ends here

  System.out.println("letterNo from db is" + letterNo);



    //2nd insert Transaction happens here 

  for (BigDecimal docId: processAnexOne.getDocId()) {

   LetterDoc letterDoc = new LetterDoc(letterNo, singledocId, null, null);


   letterDocService.insertLetterDoc(letterDoc, entryBy);



  }


我有三个事务将在这个服务类中的三个不同的表上命中。所以我的问题是,当第一个事务完成并且第二个事务出现错误时,那么在第一个事务中没有任何回滚发生。在那种情况下,我仍然在我的表中看到第一笔交易的数据,但第二笔交易出现错误。我已经为回滚声明了@Transaction 注释,并且也尝试过 (rollbackOn=Exception.class) 但如果出现错误,它不会回滚第一个事务。


翻阅古今
浏览 148回答 2
2回答

Smart猫小萌

根据Spring Doc,对于未处理的异常,会自动完成回滚。在这种情况下,您正在处理它,以便事务管理器不会看到有错误。另一方面,任何类型的未经检查的异常(扩展 RuntimeException 的异常)都会发生回滚,而无需在 @Transactional 注释中声明它们。但是,需要在 @Transactional 注释中声明已检查的注释(您需要在 catch 块中处理的注释)。最后,我建议您在最高级别的方法中添加回滚,即启动事务的方法,以确保事务行为。

Qyouu

问题出在 LetterDaoImpl.java 上,您在 saveLetter 方法中发现了任何异常。如果你捕捉到异常并且你没有把它扔回去,你就不会得到回滚。此外,您应该检查注释@Transactional,因为我很确定语法是rollbackFor() 而不是rollbackOn()。出于调试事务的目的,我通常在调试级别为 org.springframework.jdbc.datasource.DataSourceTransactionManager 启用日志。
随时随地看视频慕课网APP

相关分类

Java
我要回答