-1

I have a code in this format (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");
  }
 }
}

In my action class, i am calling the mainService.java by injecting it as a service also.

Both ServiceA and ServiceB methods called are annoted with @Transactional as well.

The weird things is, when i run this code (i make it to throw error in ServiceA method when it insert into db), the result sequence is not what i expect.

The result is:

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!

i think it is cause by the transactional annotation, but i tried to remove the transactional annotation in insertIntoDbTableOne method, but it is not helping.

Any idea how to make the system catch this error within the try catch? i cannot afford to only catch it in the action class which calls this methodTest.

Mohammadreza Khatami
  • 1,444
  • 2
  • 13
  • 27
Think Tank
  • 43
  • 8

1 Answers1

0

I just found a workaround for the problem that i had. The issue seems to be about spring transactional management, and i am posting my workaround in case anyone had similar issue in the future.

For spring @transactional methods, it will keep at the db related operations till the end of the method. That is the reason why my try catch within the methodTest cannot catch those error. When methodTest came to an end, then only those db operations will be executed.

To solve this, i created another method on the same layer as methodTest, and name it 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");
  }
 }

So, in my main action class, i will call mainService.methodTestTwo() instead. In this case, the transactional management ends when it perform methodTest(), and the error will be caught in methodTestTwo try catch !.

Hope it helps

Think Tank
  • 43
  • 8
  • Are you sure it's working? Please see [Spring @Transaction method call by the method within the same class, does not work?](https://stackoverflow.com/questions/3423972/spring-transaction-method-call-by-the-method-within-the-same-class-does-not-wo) – Sukhpal Singh Nov 15 '18 at 07:39
  • To add on to the question i asked last year, just in case others are having similar issue too.. Sukhpal are right, the method should not be in the same class. The methodTestTwo must be moved into another class in order for the transactional to works as per expected – Think Tank Oct 07 '19 at 09:25