Recently, I was looking at the code of Transaction and found that TransactionSynchronizationUtils
is too rude to execute user callback code, and all the exceptions that may be thrown in the callback method are directly swallowed.
org.springframework.transaction.support.TransactionSynchronizationUtils#triggerBeforeCompletion
public static void triggerBeforeCompletion() {
for (TransactionSynchronization synchronization : TransactionSynchronizationManager.getSynchronizations()) {
try {
synchronization.beforeCompletion();
}
catch (Throwable ex) { // Swallow all Throwable,but ThreadDeath/VirtualMachineError should throw.
logger.error("TransactionSynchronization.beforeCompletion threw exception", ex);
}
}
}
org.springframework.transaction.support.TransactionSynchronizationUtils#invokeAfterCompletion
public static void invokeAfterCompletion(@Nullable List<TransactionSynchronization> synchronizations,
int completionStatus) {
if (synchronizations != null) {
for (TransactionSynchronization synchronization : synchronizations) {
try {
synchronization.afterCompletion(completionStatus);
}
catch (Throwable ex) {
logger.error("TransactionSynchronization.afterCompletion threw exception", ex);
}
}
}
}
Strategy used in Tomcat
public static void handleThrowable(Throwable t) {
if (t instanceof ThreadDeath) {
throw (ThreadDeath) t;
}
if (t instanceof StackOverflowError) {
// Swallow silently - it should be recoverable
return;
}
if (t instanceof VirtualMachineError) {
throw (VirtualMachineError) t;
}
// All other instances of Throwable will be silently swallowed
}
Comment From: PerJoker
Thank you for your reply. Should I modify it and submit it to merge? I am a bit unclear about the process
Comment From: PerJoker
@sbrannen
Comment From: sbrannen
@PerJoker, are you suggesting that exceptions should not be swallowed if they are of type ThreadDeath
, StackOverflowError
, or VirtualMachineError
?
Or are you proposing something else?
Comment From: sbrannen
Should I modify it and submit it to merge? I am a bit unclear about the process
The status: waiting-for-triage
label on the right-hand side of this page indicates that the team has not yet assessed this issue.
Comment From: PerJoker
@PerJoker, are you suggesting that exceptions should not be swallowed if they are of type
ThreadDeath
,StackOverflowError
, orVirtualMachineError
?Or are you proposing something else?
Yes , the types of ThreadDeath
, StackOverflowError
, or VirtualMachineError
should be thrown always.
Comment From: PerJoker
@sbrannen Can I should merge?
Comment From: snicoll
Thanks for the suggestion but we believe that the code is fine as it is. With beforeCompletion
, it's part of exception recovery when something fails on transaction completion. We catch and log unexpected follow-up exceptions there so that the rest of the cleanup continues - and in particular so that the original exception is not being overridden.