galovics commented on code in PR #3120:
URL: https://github.com/apache/fineract/pull/3120#discussion_r1166402604
##########
fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java:
##########
@@ -73,4 +83,31 @@ public DataSource retrieveDataSource() {
return actualDataSource;
}
+
+ @Override
+ public void onApplicationEvent(ContextRefreshedEvent event) {
+ final List<FineractPlatformTenant> allTenants =
tenantDetailsService.findAllTenants();
+ for (final FineractPlatformTenant tenant : allTenants) {
+ initializeDataSourceConnection(tenant);
+ }
+ }
+
+ private void initializeDataSourceConnection(FineractPlatformTenant tenant)
{
+ log.debug("Initializing database connection for {}", tenant.getName());
+ final FineractPlatformTenantConnection tenantConnection =
tenant.getConnection();
+ synchronized (TENANT_TO_DATA_SOURCE_MAP) {
Review Comment:
@ruchiD this is still not thread-safe since the other accesses are not
synchronized.
Let me give you a hint how this should be implemented.
First change the map to be a ConcurrentHashMap
```
private static final Map<Long, DataSource> TENANT_TO_DATA_SOURCE_MAP = new
ConcurrentHashMap<>();
```
Then let's use an atomic operation on the HashMap to prevent the race
conditions happening due to the check-then-act approach (where one thread is
seeing a stale value and the other is not).
```
String key = tenantConnection.getConnectionId();
TENANT_TO_DATE_SOURCE_MAP.computeIfAbsent(key, (key) -> {
DataSource tenantSpecificDataSource =
dataSourcePerTenantServiceFactory.createNewDataSourceFor(tenantConnection);
try (Connection connection =
tenantSpecificDataSource.getConnection()) {
String url = connection.getMetaData().getURL();
log.debug("Established database connection with URL {}",
url);
return tenantSpecificDataSource;
} catch (SQLException e) {
log.error("Error while initializing database connection
for {}", tenant.getName(), e);
}
});
```
And similarly, you have to do the same at the other points where the map is
accessed. The key thing is to use operations where ConcurrentHashMap provides
atomicity guarantess (computeIfAbsent/Present/putIfAbsent/Present/etc)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]