@Transactional(propagation = Propagation.REQUIRES_NEW) doesn't create a new connection on JBoss EAP

173 Views Asked by At

I have a need to dynamically switch datasource in runtime (read/write to multiple MariaDB databases). I'm using multi-tenancy concept for the same.

I have not been able to get it to work for the below simple scenario though. For the first invocation of myService.persist() a connection is requested by the Spring and hence a connection associated with db1 is returned as expected. However, for the second invocation, no new connection is requested and existing connection associated with db1 is being used.

public class MainClass {
    
    ..
    
    public void main() {
        TenantContext.setCurrentTenant("db1");
        myService.persist();

        TenantContext.setCurrentTenant("db2");
        myService.persist();
    }
}
@Service
public class MyService {

    ..

    // Method is correctly declared as public and is being called from another class
    // to ensure proxy application
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void persist() {
        MyEntity entity = new MyEntity();
        entity.setName(UUID.randomUUID().toString());
        entity.setLastUpdated(new Date());


        repository.save(entity);
    }
}

The application is built on Spring Boot 2.7.17 and is being deployed on JBoss EAP 7.3 container. Datasource is configured using JNDI with below configuration in standalone.xml. I have not configured any Transaction manager in code explicitly.

<datasource jta="true" jndi-name="java:/datasources/db1" pool-name="db1" enabled="true" use-ccm="true" statistics-enabled="true">
    <connection-url>jdbc:mariadb://myhost:3306/db1</connection-url>
    <driver>maria</driver>
    <security>
        <user-name>*******</user-name>
        <password>******</password>
    </security>
    <validation>
        <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker"/>
        <check-valid-connection-sql>select 1</check-valid-connection-sql>
        <validate-on-match>true</validate-on-match>
        <background-validation>false</background-validation>
        <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter"/>
    </validation>
    <timeout>
        <set-tx-query-timeout>true</set-tx-query-timeout>
        <blocking-timeout-millis>300</blocking-timeout-millis>
        <idle-timeout-minutes>10</idle-timeout-minutes>
        <query-timeout>300</query-timeout>
        <allocation-retry>3</allocation-retry>
        <allocation-retry-wait-millis>300</allocation-retry-wait-millis>
    </timeout>
</datasource>

I do see the below log in start up log. Could it have something to do with it?

Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
1

There are 1 best solutions below

0
On

I believe, that @seenukarthi's comment has a proper link. Fillow the link and take a look at the configuration. You wrote here that you didn't declare any transaction manager, but it's strongly required since you use @Transactional.

When using the @Transactional annotation in Spring, you must add the following line to your Spring configuration file:

<tx:annotation-driven transaction-manager="transactionManager"/>

The transaction-manager property holds a reference to the transaction manager bean defined in the Spring configuration file. This code tells Spring to use the @Transaction annotation when applying the transaction interceptor. Without it, the @Transactional annotation is ignored, resulting in no transaction being used in your code.

Here is a nice article about transaction management.