Skip to content

@Transactional should treat UndeclaredThrowableException as a checked exception #26854

Closed
@Sam-Kruglov

Description

@Sam-Kruglov

I read this blogpost describing this problem:

@SneakyThrows
@Transactional
public void lombokSurprise() {
    jdbcTemplate.execute("insert into test_table values('lombok!')");
    throw new Exception("Simple exception");
}

This code is supposed to commit the transaction but it does not. The problem is that Spring wraps checked exceptions that aren't declared in the signature within an UndeclaredThrowableException over here and from that point treats it as unchecked.

I think we should treat this one as a checked exception to preserve the promised behavior. I believe it's controlled here:

/**
* The default behavior is as with EJB: rollback on unchecked exception
* ({@link RuntimeException}), assuming an unexpected outcome outside of any
* business rules. Additionally, we also attempt to rollback on {@link Error} which
* is clearly an unexpected outcome as well. By contrast, a checked exception is
* considered a business exception and therefore a regular expected outcome of the
* transactional business method, i.e. a kind of alternative return value which
* still allows for regular completion of resource operations.
* <p>This is largely consistent with TransactionTemplate's default behavior,
* except that TransactionTemplate also rolls back on undeclared checked exceptions
* (a corner case). For declarative transactions, we expect checked exceptions to be
* intentionally declared as business exceptions, leading to a commit by default.
* @see org.springframework.transaction.support.TransactionTemplate#execute
*/
@Override
public boolean rollbackOn(Throwable ex) {
return (ex instanceof RuntimeException || ex instanceof Error);
}

So, we could append || ex instanceof UndeclaredThrowableException to solve it.

It will be a breaking change, but I think most people expect it to work that way anyway.

Metadata

Metadata

Assignees

Labels

in: dataIssues in data modules (jdbc, orm, oxm, tx)status: declinedA suggestion or change that we don't feel we should currently apply

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions