views:

84

answers:

1

I'm using Spring 2.5 transaction management and I have the following set-up:

Bean1

@Transactional(noRollbackFor = { Exception.class })
public void execute() {
  try {
    bean2.execute();
  } catch (Exception e) {
    // persist failure in database (so the transaction shouldn't fail)
    // the exception is not re-thrown
  }
}

Bean2

@Transactional
public void execute() {
  // do something which throws a RuntimeException
}

The failure is never persisted into DB from Bean1 because the whole transaction is rolled back.

I don't want to add noRollbackFor in Bean2 because it's used in a lot of places which don't have logic to handle runtime exceptions properly.

Is there a way to avoid my transaction to be rolled back only when Bean2.execute() is called from Bean1?

Otherwise, I guess my best option is to persist my failure within a new transaction? Anything else clean I can do?

+1  A: 

This is one of the caveats of annotations... your class is not reusable!

If you'd configure your transactions in the XML, if would have been possible.

Assuming you use XML configuration: if it's not consuming expensive resources, you can create another instance of bean2 for the use of the code you specified. That is, you can configure one been as you specified above, and one with no roll back for exception.

Eran Harel
Thanks, that's a good remark. Anyway, the whole set-up of transactions in my application was very bad, with transactions declared at the DAO level. Because of that I still have some embedded transactions like shown in the question but I'll try to refactor when I get a chance.
Damien