简体   繁体   中英

Is there an easier way to combine @Transactional with logging?

I'm trying out Spring for the first time but am having a problem with @Transactional. There are certain parts of my app that I need to log exceptions in the method instead of bubbling them up to, say, main() . The issue though is that those methods which are labeled with @Transactional won't be rolled back if an exception occurs.

In short, this wont' work

@Transactional
public void doStuff() {
    try {
        //Do something that might cause an Exception
    } catch (Exception e) {
        log.error("Exception when trying to do stuff", e);
    }
}

Because from my understanding the transaction will never be rolled back if an exception occurs.

The only solution I could come up with:

public void doStuff() {
    try {
        doStuff0();
    } catch (Exception e) {
        log.error("Error encountered while attempting to join servers", e);
    }
}

@Transactional
protected void doStuff0() {
    //Do something that might cause an Exception
}

That's ugly though, uses a pattern I don't like, and is in this example almost twice as much code.

Is there another alternative to log the exception AND rollback the transaction?

There is in fact a simple way to do what you want. Architectural Astronaut discussions about if it's a good idea or when it' appropriate aside, sometimes you just need it to work :) :

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

Easy as that.

Just rethrow the exception:

@Transactional
public void doStuff() {
    try {
        //Do something that might cause an Exception
    } catch (Exception e) {
      log.error("Exception when trying to do stuff", e);
      throw e;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM