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]
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
.Here is a nice article about transaction management.