Feature 296385 caching 1#273
Conversation
Added caching on dataset schema service methods. Refs #296385 Added caching on data schema service methods. Refs #296385
74b0d48 to
1fc4643
Compare
| @Autowired | ||
| @Lazy | ||
| private DatasetSchemaService self; | ||
|
|
There was a problem hiding this comment.
Since declaring self variables is not a thing we do in Java, please add a comment here to document this declaration, so it is obvious you are declaring a self variable to make Spring AOP work for self invocations of @transactional and @cachable, and @lazy to avoid circular dependancy error on startup. Intent comments are always welcome!
| * Redis Cache Manager for local profile. | ||
| * Uses a standalone Redis connection to manage caches for | ||
| * {@code dataSchema} and {@code uniqueConstraints}. | ||
| * TTLs are configurable via Consul keys {@code cache.dataSchema.ttl} |
There was a problem hiding this comment.
Where is the cache for {@code uniqueConstraints}? Delete the javadoc reference if not needed.
There was a problem hiding this comment.
These are leftovers after splitting the implementation. Thanks for noticing.
| * Redis Cache Manager for non-local profiles (dev, staging, production). | ||
| * Uses a Redis Sentinel connection for high availability to manage caches for | ||
| * {@code dataSchema} and {@code uniqueConstraints}. | ||
| * TTLs are configurable via Consul keys {@code cache.dataSchema.ttl} |
There was a problem hiding this comment.
These are leftovers after splitting the implementation. Thanks for noticing.
| * @throws EEAException the EEA exception | ||
| */ | ||
| @Override | ||
| @Transactional |
There was a problem hiding this comment.
Transaction will not work for the invocation of this method on lines 2998 and 3390 of this class as they are not called through the self reference. Is this intentional? We don't want it to work there?
There was a problem hiding this comment.
This is surely not intentional. We do want @Transactional to work there.
The two internal callers are:
updateImportFieldSchemacallsupdateFieldSchema(...)directly viathisprocessToModifyTheFKcallsupdateFieldSchema(...)directly viathis
Both are private methods, and neither routes through self, so the @Transactional annotation will be silently ignored for those two call paths.
Those calls should be routed through self otherwise:
- In
updateImportFieldSchema: There are multiple operations happen in sequence. IfupdateFieldSchemafails midway, without a transaction boundary those preceding side effects won't be rolled back, leaving the schema in an inconsistent state. - In
processToModifyTheFK: We have multiple field updates loop. A failure mid-loop would leave partially updated FK relations.
| * @param referenceDataset the reference dataset | ||
| */ | ||
| @Override | ||
| @Transactional |
There was a problem hiding this comment.
@transactional here will only work if an exception is thrown from schemasRepository.updateReferenceDataset() on line 2606. updateTableSchema() on line 2614 can fail to update any of the tables and the transaction will still be considered valid, as the exception thrown by updateTableSchema() is swallowed. Let's discuss this with Fotis.
There was a problem hiding this comment.
You are correct. We have two problems here:
- The swallowed exception: If
updateTableSchemafails for any or all tables in the loop, the caughtEEAExceptionis only logged. No exception propagates out, so Spring's transaction manager sees a clean return and commits. TheschemasRepository.updateReferenceDataset()change persists even if none of the tables were actually updated, leaving the schema in an inconsistent state. - The
thisinvocation: Even if the exception was allowed to propagate,updateTableSchemais called viathisrather thanself, meaning its own@Transactionalannotation is also bypassed, and more critically the call won't participate correctly in the outer transaction anyway.
I see two options here:
- Remove the try-catch and let it propagate(either all tables update or none):
// no try-catch, exception propagates and triggers rollback
self.updateTableSchema(datasetId, table, true);
- Keep the try-catch but acknowledge that
@Transactionalis misleading here and remove it, since it provides no real protection anyway.
try {
self.updateTableSchema(datasetId, table, true);
} catch (EEAException e) {
LOG.error(...);
}
Summary
Adds caching improvements for Dataschema service.
Changes
Testing
Notes
Please review especially the caching strategy and invalidation logic.