From fc1c2f192e72b4109e066ba4eb539fece2884859 Mon Sep 17 00:00:00 2001 From: GiuseppeS Date: Thu, 27 Nov 2025 17:22:15 +0100 Subject: [PATCH] Migliorata gestione DBMS Change Tracking in caso di disallineamento min valid version --- .../component/DbmsChangeTracker.java | 9 ++++- .../component/DbmsChangeTrackerComponent.java | 21 +++++++++-- ...angeTrackerInvalidMinVersionException.java | 27 ++++++++++++++ .../events/TableTrackingResettedEvent.java | 11 ++++++ .../dynamic_cache/EntityCacheComponent.java | 35 +++++++++++++++++++ 5 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/exception/DbmsChangeTrackerInvalidMinVersionException.java create mode 100644 ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/events/TableTrackingResettedEvent.java diff --git a/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTracker.java b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTracker.java index 620bb41178..872564a236 100644 --- a/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTracker.java +++ b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTracker.java @@ -140,8 +140,13 @@ public class DbmsChangeTracker { for (String trackedTable : trackedTables) { long minValidVersion = getMinValidVersion(trackedTable); + if (currentVersion < minValidVersion) { - throw new SQLException("Change Tracking on table " + trackedTable + " has been reset. Current version: " + currentVersion + ", Min valid version: " + minValidVersion); + if (eventListener != null) { + eventListener.onTrackingResetted(); + currentVersion = retrieveCurrentVersion(); + return; + } } final List detectedChanges = retrieveChangeList(trackedTable); @@ -291,5 +296,7 @@ public class DbmsChangeTracker { void onUpdateDetected(String tableName, HashMap primaryKey) throws Exception; void onDeleteDetected(String tableName, HashMap primaryKey) throws Exception; + + void onTrackingResetted() throws Exception; } } diff --git a/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTrackerComponent.java b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTrackerComponent.java index c579066094..43c05468da 100644 --- a/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTrackerComponent.java +++ b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/DbmsChangeTrackerComponent.java @@ -5,6 +5,7 @@ import it.integry.annotations.PostContextConstruct; import it.integry.ems.dbms_change_tracker.model.events.TableRecordDeletedEvent; import it.integry.ems.dbms_change_tracker.model.events.TableRecordInsertedEvent; import it.integry.ems.dbms_change_tracker.model.events.TableRecordUpdatedEvent; +import it.integry.ems.dbms_change_tracker.model.events.TableTrackingResettedEvent; import it.integry.ems.migration._base.IntegryCustomerDB; import it.integry.ems.sync.MultiDBTransaction.Connection; import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager; @@ -63,8 +64,8 @@ public class DbmsChangeTrackerComponent { private void enableAllChangeTracking() throws Exception { for (Map.Entry entrySet : activeChangeTrackers.entrySet()) { - IntegryCustomerDB customerDB = entrySet.getKey(); - DbmsChangeTracker dbmsChangeTracker = entrySet.getValue(); + final IntegryCustomerDB customerDB = entrySet.getKey(); + final DbmsChangeTracker dbmsChangeTracker = entrySet.getValue(); try { @@ -91,6 +92,11 @@ public class DbmsChangeTrackerComponent { public void onDeleteDetected(String tableName, HashMap primaryKey) { onItemDeleted(customerDB, tableName, primaryKey); } + + @Override + public void onTrackingResetted() throws Exception { + requestGlobalReset(customerDB); + } }); dbmsChangeTracker.startTracking(); @@ -104,7 +110,11 @@ public class DbmsChangeTrackerComponent { @Scheduled(fixedDelay = 5, timeUnit = TimeUnit.SECONDS) private void checkAllChanges() throws Exception { for (DbmsChangeTracker dbmsChangeTracker : activeChangeTrackers.values()) { - dbmsChangeTracker.checkForChanges(); + try { + dbmsChangeTracker.checkForChanges(); + } catch (Exception e) { + logger.error("Errore durante il controllo delle modifiche nel DbmsChangeTracker.", e); + } } } @@ -124,4 +134,9 @@ public class DbmsChangeTrackerComponent { applicationEventPublisher.publishEvent(new TableRecordDeletedEvent(this, customerDB, tableName, primaryKey)); } + private void requestGlobalReset(IntegryCustomerDB customerDB) { + logger.warn("Table tracking resetted in profileDb {} ", customerDB.getValue()); + applicationEventPublisher.publishEvent(new TableTrackingResettedEvent(this, customerDB)); + } + } diff --git a/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/exception/DbmsChangeTrackerInvalidMinVersionException.java b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/exception/DbmsChangeTrackerInvalidMinVersionException.java new file mode 100644 index 0000000000..4cf875e5cc --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/component/exception/DbmsChangeTrackerInvalidMinVersionException.java @@ -0,0 +1,27 @@ +package it.integry.ems.dbms_change_tracker.component.exception; + +public class DbmsChangeTrackerInvalidMinVersionException extends Exception { + + private final String tableName; + private final long currentVersion; + private final long minValidVersion; + + public DbmsChangeTrackerInvalidMinVersionException(String tableName, long currentVersion, long minValidVersion) { + super("Change Tracking on table " + tableName + " has been reset. Current version: " + currentVersion + ", Min valid version: " + minValidVersion); + this.tableName = tableName; + this.minValidVersion = minValidVersion; + this.currentVersion = currentVersion; + } + + public String getTableName() { + return tableName; + } + + public long getCurrentVersion() { + return currentVersion; + } + + public long getMinValidVersion() { + return minValidVersion; + } +} diff --git a/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/events/TableTrackingResettedEvent.java b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/events/TableTrackingResettedEvent.java new file mode 100644 index 0000000000..796b9669a8 --- /dev/null +++ b/ems-core/src/main/java/it/integry/ems/dbms_change_tracker/model/events/TableTrackingResettedEvent.java @@ -0,0 +1,11 @@ +package it.integry.ems.dbms_change_tracker.model.events; + +import it.integry.ems.migration._base.IntegryCustomerDB; +import it.integry.event.BaseCustomerDBEvent; + +public class TableTrackingResettedEvent extends BaseCustomerDBEvent { + + public TableTrackingResettedEvent(Object source, IntegryCustomerDB customerDB) { + super(source, customerDB); + } +} diff --git a/ems-core/src/main/java/it/integry/ems/dynamic_cache/EntityCacheComponent.java b/ems-core/src/main/java/it/integry/ems/dynamic_cache/EntityCacheComponent.java index 07ae8217b3..38e783f929 100644 --- a/ems-core/src/main/java/it/integry/ems/dynamic_cache/EntityCacheComponent.java +++ b/ems-core/src/main/java/it/integry/ems/dynamic_cache/EntityCacheComponent.java @@ -6,6 +6,7 @@ import it.integry.ems.dbms_change_tracker.component.DbmsChangeTrackerComponent; import it.integry.ems.dbms_change_tracker.model.events.TableRecordDeletedEvent; import it.integry.ems.dbms_change_tracker.model.events.TableRecordInsertedEvent; import it.integry.ems.dbms_change_tracker.model.events.TableRecordUpdatedEvent; +import it.integry.ems.dbms_change_tracker.model.events.TableTrackingResettedEvent; import it.integry.ems.dto.EntityHierarchy; import it.integry.ems.migration._base.IntegryCustomerDB; import it.integry.ems.sync.MultiDBTransaction.Connection; @@ -84,6 +85,16 @@ public class EntityCacheComponent implements ApplicationListener { } } + private void refreshCacheGlobal(IntegryCustomerDB customerDB) throws Exception { + try (MultiDBTransactionManager mdb = new MultiDBTransactionManager(customerDB)) { + Connection conn = mdb.getPrimaryConnection(); + for (Map.Entry> enabledEntity : enabledEntities.entrySet()) { + String tableName = enabledEntity.getKey(); + refreshCacheForEntity(conn, customerDB, tableName); + } + } + } + private void refreshCacheForEntity(IntegryCustomerDB customerDB, String tableName) throws Exception { try (MultiDBTransactionManager mdb = new MultiDBTransactionManager(customerDB)) { Connection conn = mdb.getPrimaryConnection(); @@ -142,6 +153,13 @@ public class EntityCacheComponent implements ApplicationListener { } else if (event instanceof TableRecordDeletedEvent) { handleRecordDeleted((TableRecordDeletedEvent) event); + } else if (event instanceof TableTrackingResettedEvent) { + try { + handleTableTrackingResetted((TableTrackingResettedEvent) event); + } catch (Exception e) { + throw new RuntimeException(e); + } + } } @@ -197,6 +215,11 @@ public class EntityCacheComponent implements ApplicationListener { .remove(entityPrimaryKey); } + private void handleTableTrackingResetted(TableTrackingResettedEvent event) throws Exception { + resetTablesCache(event.getCustomerDB()); + refreshCacheGlobal(event.getCustomerDB()); + } + private ConcurrentHashMap, EntityBase> retrieveEntityList(Connection connection, String tableName, Class clazz) throws SQLException, DataConverterNotFoundException, InstantiationException, IllegalAccessException { String sql = "SELECT * FROM " + tableName; @@ -243,6 +266,18 @@ public class EntityCacheComponent implements ApplicationListener { } + private void resetTableCache(IntegryCustomerDB customerDB, String tableName) { + if (entityCache.containsKey(customerDB) && entityCache.get(customerDB).containsKey(tableName)) { + entityCache.get(customerDB).remove(tableName); + } + } + + + private void resetTablesCache(IntegryCustomerDB customerDB) { + entityCache.remove(customerDB); + } + + private boolean isCacheEnabled(IntegryCustomerDB customerDB, String tableName) { return (entityCache.containsKey(customerDB) && entityCache.get(customerDB).containsKey(tableName)) || !(UtilityDebug.isDebugExecution() || UtilityDebug.isIntegryServer());