0

I am currently using the spring @transactional annotation to make a series of database changes. Upon any exception that is not thrown by me (e.g. my UPDATA clause violates the column constraints in the table), the transaction is successfully rolled back. However, no error message is printed in the console.

I would like to handle such cases manually. For example, I may want to record such events in a txt file. I am wondering if there is a way for me to catch such exceptions(or more accurately, have a listener for such events).

Relevant Code

@Transactional
public class DefaultFooService implements FooService {
    public Foo getFoo(String fooName) {
        INSERT A ROW
        UPDATE A ROW
    }
}

In the code above, assume that INSERT A ROW succeeds but UPDATE A ROW failed due to SQLException(for example due to column constraints violation). Currently, no error message is printed in the console with logging set to INFO. When I use DEBUG, I could see that SQLException is detected and the tx is rolled back.

How could I be notified when the transaction failed and is rolled back?

======

This question is somewhat different from dynamically register transaction listener with spring? in that I want to be notified if and only if my transaction has failed and I want to know why it has failed.


To illustrate the problem differently. In the following code block, no exception will be thrown (printed in stdout) currently. How could I catch/handle the RuntimeException?

@Transactional
public class DefaultFooService implements FooService {
    public Foo getFoo(String fooName) {
        throw new RuntimeException();
    }
}
The Yellow
  • 47
  • 8
  • @Dherik This question is somewhat different from dynamically register transaction listener with spring? in that I want to be notified if and only if my transaction has failed and I want to know why it has failed. – The Yellow Jun 15 '18 at 14:19
  • right. I will remove my close vote :) – Dherik Jun 15 '18 at 14:21
  • May you have a catch block without a printstacktrace() ? If it's detecting the ConstraintViolation but there's no catch block where doing the rollback means that an utility class is handling this. You could add a throws declaration on it and handle it outside the method. – Carlos López Marí Jun 15 '18 at 14:23
  • You can set the logging level to TRACE on the package `org.springframework.transaction` to get the spring transaction logs output – SrThompson Jun 15 '18 at 14:30

1 Answers1

-1

You can use try-catch-blocks around the database operations and do whatever you want with the exception information. Then, if you decide you still want to roll back you can throw the exception from inside the catch block. Or if you really want to get fancy:

@Transactional(rollbackFor={FancyOwnException.class})

or even inside the catch manually:

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
Alim Özdemir
  • 2,396
  • 1
  • 24
  • 35
  • The problem is that it is not my own exception that is thrown. In the case presented above, 'SQLException' is thrown and it cannot be caught using try and catch block. – The Yellow Jun 15 '18 at 14:31
  • You can catch any Exception, you mean the SQLException is wrapped by Spring/Hibernate. To test catch(DataAccessException e) { if(e.getRootCause() instanceof SQLException) { do your thing. } } – Alim Özdemir Jun 15 '18 at 15:29