Add #closeExceptionally(Throwable) to AutoClosable
Kasper Nielsen
kasperni at gmail.com
Fri Mar 22 18:40:20 UTC 2019
Hi,
I was looking at some example on transaction management the other day.
And no matter if it is JPA, JDBC og something else. They all look
similar to this (or uses some kind of @Transactional annotation
coupled with AOP)
UserTransaction utx = entityManager.getTransaction();
try {
utx.begin();
businessLogic();
utx.commit();
} catch(Exception ex) {
utx.rollback();
throw ex;
}
I think we can all agree that this code is repetitive, error-prone and
not very readable.
And if you have a large codebase, chances are you might forget
commit() or rollback() somewhere. And god forbid you start nesting the
calls.
You cannot really use try-with-resources here because you need to
perform one kind of
"close" operation if your business logic succeed and another if it fails.
So I though why not add the following method to AutoClosable
default closeExceptionally(Throwable cause) throws Exception {
close();
}
With the implementation of try-with-resources changing to
try ResourceSpecification_tail
Block
catch (Throwable #t) {
#primaryExc = #t;
throw #t;
} finally {
if (Identifier != null) {
if (#primaryExc != null) {
try {
Identifier.close(); ------------->
Identifier.closeExceptionally(primaryExc);
} catch (Throwable #suppressedExc) {
#primaryExc.addSuppressed(#suppressedExc);
}
} else {
Identifier.close();
}
}
}
This would allow you use something much simpler.
try (var ignore = entityManager.runInNewTransaction()) {
businessLogic();
}
It does change the semantics on Closable a bit. And it might be
problematic that your code will compile fine on older Java versions,
but not work as expected because closeExceptionally is never invoked.
However, I think it is a net win
Thoughts?
/Kasper
More information about the amber-dev
mailing list