I would like to report this issue, unsure if it is a bug, or a request for enhancement, or expected behaviour.

With version 6.0.13, I have noticed that attributes to class-level @Transactional are not merged to method-level @Transactional when omitted on the latter.

Example

@Repository
@Transactional(transactionManager="myTransactionManager")
public class MyManager {

    @Transactional(propagation=REQUIRES_NEW)
    void insert(DTO dto){...}

    @Transactional(readOnly=true)
    DTO findById(Long id) {...}


}

Expected behaviour vs actual

I expected that method insert uses both the transactionManager attribute and the propagation, but in practice it uses only the propagation.

A working example, which is not currently provided, can clearly show an end to end example where two transaction managers are defined in the context. If none of them is @Primary, then Spring will complain more than one transaction manager exists for methods annotated @Transactional for which the txManager is not defined. The basic idea, in that case, is that the class defines the tx manager for all methods, and specific methods define a different propagation, isolation, or readonly status

Summary of POC

(I will provide a full POC in a repository after triage)

  • Define two PlatformTransactionManager beans, e.g. they point to two different data sources
  • Do not annotate any @Transactional
  • Create a bean whose class is annotated @Transactional(transactionManager = "[any]"), define as many methods as you like
  • Methods not annotated @Transactional inherit annotation from the class, this is expected and okay
  • Annotate another method @Transactional but do not specify the transactionManager at the method level
  • These methods will throw an exception that multiple TransactionManagers are defined

Thank you for your time. We have currently worked the problem around in our business scenario by specifying transactionManager for every method annotated.

Comment From: quaff

IMO some attributes of @Transactional are applicable for merging and others are not, for example propagation, maybe we should introduce new annotation like @TransactionalConfig to contains those common attributes at class level?

Comment From: jhoeller

There is indeed a design mismatch here in that class-level @Transactional usage applies as a default for non-annotated methods and not as common configuration settings for method annotations. We'll address this for 6.2 in #24291: see https://github.com/spring-projects/spring-framework/issues/24291#issuecomment-1824619867