Skip to content

Detect invalid transaction configuration for transactional event listeners #30679

@odrotbohm

Description

@odrotbohm

Problem

It's common practice to use a simple (no custom attributes) @Transactional on methods to execute them wrapped in a transaction. Unfortunately, for methods declared as @TransactionalEventListener, this doesn't work as expected:

@Component
class SomeListener {

  @Transactional
  @TransactionalEventListener
  void on(SomeEvent event) { /* … */ }
}

Those methods are invoked in the transaction cleanup phase of an original, other transaction. This means that this particular, other transaction is still running, although in an undefined state. With a simple @Transactional declared on those methods, the code would be executed in an undefined transactional state. An obvious solution to this problem is to declare a Propagation of REQUIRES_NEW on the listener method, so that it will run in a new transaction:

@Component
class SomeListener {

  @Transactional(propagation = Propagation.REQUIRES_NEW)
  @TransactionalEventListener
  void on(SomeEvent event) { /* … */ }
}

Proposed solution

It would be nice if the erroneous arrangement shown above would be rejected, ideally at bootstrap (potentially even AOT?) time. We have to consider that a plain @Transactional is still valid in the case of the method declared to be invoked asynchronously (using @Async). In other words, a declaration like this is still valid, as the asynchronous invocation triggers the execution on a separate thread and thus a clean slate regarding transactions.

@Component
class SomeListener {

  @Async
  @Transactional
  @TransactionalEventListener
  void on(SomeEvent event) { /* … */ }
}

Metadata

Metadata

Assignees

Labels

in: dataIssues in data modules (jdbc, orm, oxm, tx)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions