From 5667bc89be50ce4d985526db63059a1cf067f7fe Mon Sep 17 00:00:00 2001 From: Adam Saghy Date: Thu, 12 Dec 2024 15:50:09 +0100 Subject: [PATCH] FINERACT-2081: Consider read-only all the transactions when the connection is read-only --- .../TomcatJdbcDataSourcePerTenantService.java | 6 ++---- .../persistence/ExtendedJpaTransactionManager.java | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java index fb829d66479..9e11be36c8f 100644 --- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java +++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/database/TomcatJdbcDataSourcePerTenantService.java @@ -70,10 +70,8 @@ public DataSource retrieveDataSource() { Long tenantConnectionKey = tenantConnection.getConnectionId(); // if tenantConnection information available switch to the // appropriate datasource for that tenant. - actualDataSource = TENANT_TO_DATA_SOURCE_MAP.computeIfAbsent(tenantConnectionKey, (key) -> { - DataSource tenantSpecificDataSource = dataSourcePerTenantServiceFactory.createNewDataSourceFor(tenantConnection); - return tenantSpecificDataSource; - }); + actualDataSource = TENANT_TO_DATA_SOURCE_MAP.computeIfAbsent(tenantConnectionKey, + (key) -> dataSourcePerTenantServiceFactory.createNewDataSourceFor(tenantConnection)); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/persistence/ExtendedJpaTransactionManager.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/persistence/ExtendedJpaTransactionManager.java index 667186fee2e..5d85df640f7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/persistence/ExtendedJpaTransactionManager.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/persistence/ExtendedJpaTransactionManager.java @@ -20,6 +20,8 @@ import jakarta.persistence.EntityManager; import jakarta.persistence.FlushModeType; +import java.sql.Connection; +import java.sql.SQLException; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Consumer; @@ -41,7 +43,7 @@ public ExtendedJpaTransactionManager() { @Override protected void doBegin(Object transaction, TransactionDefinition definition) { super.doBegin(transaction, definition); - if (isReadOnlyTx(transaction)) { + if (isReadOnlyConnection() || isReadOnlyTx(transaction)) { EntityManager entityManager = getCurrentEntityManager(); if (entityManager != null) { entityManager.setFlushMode(FlushModeType.COMMIT); @@ -52,7 +54,7 @@ protected void doBegin(Object transaction, TransactionDefinition definition) { @Override protected void doCommit(DefaultTransactionStatus status) { - if (isReadOnlyTx(status.getTransaction())) { + if (isReadOnlyConnection() || isReadOnlyTx(status.getTransaction())) { EntityManager entityManager = getCurrentEntityManager(); if (entityManager != null) { entityManager.clear(); @@ -62,6 +64,14 @@ protected void doCommit(DefaultTransactionStatus status) { invokeLifecycleCallbacks(TransactionLifecycleCallback::afterCommit); } + private boolean isReadOnlyConnection() { + try (Connection connection = getDataSource().getConnection()) { + return connection.isReadOnly(); + } catch (SQLException e) { + throw new IllegalStateException(e); + } + } + @Override protected void doCleanupAfterCompletion(Object transaction) { super.doCleanupAfterCompletion(transaction);