@ Транзакция не будет отменена весной MVC - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть конфигурация на основе классов, поэтому для отката транзакции. Я использовал 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());
}

Так что в моем классе Service я объявил @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);


  }
 //2nd insert Transaction ends here 

   //3rd insert Transaction happens here 
  for (LetterDocOther letterDoc: processAnexOne.getLetterDocOthers()) {
   System.out.println("entered hereasfdsafsdsdfg");
   LetterDoc letterD = new LetterDoc(letterNo, letterDoc.getDocId(), null, "I",
    letterDoc.getOthersDescription());
   letterD.setEntryBy(entryBy);
   letterDocService.insertLetterDocWithDescription(letterD);
  }
 //3rd insert Transaction ends here 
 }

}

У меня есть три транзакции, которые попадут на три разные таблицы в этом классе обслуживания. Так что моя проблема в том, что когда 1-я транзакция выполнена и во 2-й транзакции возникает ошибка, то нетЛюбой откат происходит в 1-й транзакции. В этом случае я все еще вижу данные 1-й транзакции в своей таблице, но ошибка происходит во 2-й транзакции.Я объявил аннотацию @Transaction для отката и также попытался (rollbackOn = Exception.class), но она не откатывает первую транзакцию, если есть ошибка.

В моем pom.xml я добавил:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>4.3.7.RELEASE</version>
</dependency>

LetterServiceImpl.java

@Service
public class LetterServiceImpl implements LetterService {

    @Autowired
    private LetterDao letterDao;

    @Override
    @Transactional(rollbackOn=Exception.class)
    public BigDecimal insertLetter(Letter letter) {
        BigDecimal letter1=letterDao.saveLetter(letter);
        return letter1;
    }
}

LetterDaoImpl.java

@Override
    public BigDecimal saveLetter(Letter letter) {
        try {
        System.out.println("hitted123 here");
        SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(jdbcTemplate).withProcedureName("PCPR_ADD_LETTER");
        Map<String, Object> inParamMap = new HashMap<String, Object>();
        System.out.println(letter.getLetterId());
        inParamMap.put("P_LETTER_NO",null);
        inParamMap.put("P_LETTER_ID",letter.getLetterId());
        inParamMap.put("P_SIGNATARY",letter.getSignatary());
        inParamMap.put("P_LETTER_BOX",letter.getLetterBox());
        inParamMap.put("P_ENTRY_BY",letter.getEntryBy());
        inParamMap.put("P_R_STATUS","I");
        inParamMap.put("P_REMINDER_YES_NO","N");

        System.out.println("hitted1234 here");
        SqlParameterSource in = new MapSqlParameterSource(inParamMap);
        System.out.println("hitted123456789 here");
        //Map<String, Object> out = simpleJdbcCall.execute(in);
        BigDecimal letterNO =  (BigDecimal) simpleJdbcCall.execute(in).get("P_LETTER_NO");

        System.out.println("hitted12345 here"+letterNO);
        return letterNO;
        } catch(Exception e) {
            e.printStackTrace();
        }
        return null;

    }

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Согласно Spring Doc , откат выполняется автоматически для необработанных исключений.В этом случае вы обрабатываете его, поэтому менеджер транзакций не увидит, что произошла ошибка.

С другой стороны, откат будет происходить с любым неконтролируемым исключением (с расширением RuntimeException) без необходимостиобъявите их в аннотации @Transactional.Однако проверенную аннотацию (те, которые вам нужно обработать в блоках перехвата) необходимо объявить в аннотации @Transactional.

Наконец, я бы предложил добавить откат в методе самого высокого уровня, то естьтот, который запускает транзакцию, чтобы обеспечить транзакционное поведение.

0 голосов
/ 05 февраля 2019

Проблема в LetterDaoImpl.java, вы перехватываете любое исключение в методе saveLetter.Если вы перехватываете исключение и не отбрасываете его, вы не получаете отката.

Кроме того, вам следует проверить аннотацию @Transactional, потому что я почти уверен, что вместо нее используется синтаксис rollbackFor ()of rollbackOn ().

В целях отладки транзакций я обычно включаю журнал на уровне DEBUG для org.springframework.jdbc.datasource.DataSourceTransactionManager.

...