StackOverflow question

Spring Boot version: 3.2.1

If I use the following two services:

@Service
class Service1(
    private val service2: Service2
) {

    private val log = LoggerFactory.getLogger(this.javaClass)

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    fun method1() {
        log.error("Name from TransactionAspectSupport: " + TransactionAspectSupport.currentTransactionStatus().transactionName)
        log.error("Name from TransactionSynchronizationManager: " + TransactionSynchronizationManager.getCurrentTransactionName())
        service2.method2()
    }
}

@Service
class Service2 {

    private val log = LoggerFactory.getLogger(this.javaClass)

    @Transactional
    fun method2() {
        log.error("Name from TransactionAspectSupport: " + TransactionAspectSupport.currentTransactionStatus().transactionName)
        log.error("Name from TransactionSynchronizationManager: " + TransactionSynchronizationManager.getCurrentTransactionName())
    }
}

the following is printed:

2024-02-22T13:15:35.240+03:00 ERROR 21308 --- [sb-repro] [nio-8080-exec-1] c.r.s.persistence.service.Service1       : Name from TransactionAspectSupport: com.romankudryashov.sbrepro.persistence.service.Service1.method1
2024-02-22T13:15:35.240+03:00 ERROR 21308 --- [sb-repro] [nio-8080-exec-1] c.r.s.persistence.service.Service1       : Name from TransactionSynchronizationManager: com.romankudryashov.sbrepro.persistence.service.Service1.method1
2024-02-22T13:15:35.240+03:00 ERROR 21308 --- [sb-repro] [nio-8080-exec-1] c.r.s.persistence.service.Service2       : Name from TransactionAspectSupport: com.romankudryashov.sbrepro.persistence.service.Service2.method2
2024-02-22T13:15:35.240+03:00 ERROR 21308 --- [sb-repro] [nio-8080-exec-1] c.r.s.persistence.service.Service2       : Name from TransactionSynchronizationManager: com.romankudryashov.sbrepro.persistence.service.Service1.method1

That is TransactionAspectSupport and TransactionSynchronizationManager behavior differs for method2. And TransactionAspectSupport mistakenly prints wrong transaction name.

If I remove @Transactional from method2, all is correct.

To reproduce, you can use: https://github.com/rkudryashov/sb-repro and call http://localhost:8080/test

Comment From: jhoeller

This is a consequence of the different meaning of "transaction" for those two calls: TransactionAspectSupport.currentTransactionStatus() exposes the locally declared transaction boundary as managed by the aspect (even if it ends up participating in an outer transaction at runtime where the local boundary is less relevant), whereas TransactionSynchronizationManager.getCurrentTransactionName() exposes the current (outer) resource transaction.

Since TransactionAspectSupport.currentTransactionStatus() is a rather internal API and shares behavior with TransactionCallback exposure in TransactionTemplate usage, the behavior should rather remain as it is. We need to document that difference though and suggest TransactionSynchronizationManager as the primary API to interact with the actual resource transaction.