Исключение Java выброшено несмотря на то, что есть оператор try catch - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть код в этом формате (java + spring):

@Service
public class mainService{

@Inject 
 private ServiceA a;

@Inject 
private ServiceB b;

@Transactional
public void methodTest{

  try{
    System.out.println("Start");
    a.insertIntoDbTableOne();
    b.insertIntoDbTableTwo();
  }catch(Throwable e){
    e.printStackTrace();
    System.out.println("This is the catch statement");
  }finally{
   System.out.println("this is finally");
  }
 }
}

В моем классе действий я вызываю mainService.java, внедряя его также в качестве службы.

Оба метода ServiceA и ServiceB также помечены @Transactional.

Странно то, что когда я запускаю этот код (я делаю это, чтобы выдавать ошибку в ServiceA метод, когда он вставляется в БД), последовательность результатов не то, что я ожидаю.

Результат:

1. "Start" is printed
2  Do stuff in insertIntoDbTableOne method (without inserting into db)
3. Do stuff in insertIntoDbTableTwo method (without inserting into db)
4. "this is finally" is printed
5. The system tries to insert the record the db which should be inserted in step 2 and hit error!

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

Есть идеи, как заставить систему перехватить эту ошибку при попытке перехвата?я не могу позволить себе поймать его только в классе действий, который называет это methodTest.

1 Ответ

0 голосов
/ 15 ноября 2018

Я только что нашел решение этой проблемы.Похоже, проблема заключается в весеннем управлении транзакциями, и я публикую свой обходной путь на случай, если у кого-нибудь возникнет аналогичная проблема в будущем.

Для методов Spring @transactional он будет продолжать выполнять операции, связанные с БД, до концаметод.По этой причине моя попытка перехвата в методе Test не может перехватить эту ошибку.Когда methodTest подошел к концу, будут выполняться только те операции с БД.

Чтобы решить эту проблему, я создал другой метод на том же слое, что и methodTest, и назовите его methodTestTwo ()

@Transactional
public void methodTest{
    a.insertIntoDbTableOne();
    b.insertIntoDbTableTwo();
 }

public void methodTestTwo{
  try{
    System.out.println("Start");
    methodTest();
  }catch(Throwable e){
    e.printStackTrace();
    System.out.println("This is the catch statement");
  }finally{
   System.out.println("this is finally");
  }
 }

Итак, в моем классе основного действия я буду вызывать mainService.methodTestTwo ().В этом случае управление транзакциями завершается, когда он выполняет methodTest (), и ошибка будет обнаружена в methodTestTwo try catch!.

Надеюсь, это поможет

...