mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#726 - L2 cache returns stale data -> change such that when using "local L2 caching" the changes to L2 cache propagate in foreground
This commit is contained in:
@@ -5,6 +5,15 @@ package com.avaje.ebean.cache;
|
||||
*/
|
||||
public interface ServerCacheManager {
|
||||
|
||||
/**
|
||||
* Return true if the L2 caching is local.
|
||||
* <p>
|
||||
* Local L2 caching means that the cache updates should occur in foreground
|
||||
* rather than background processing.
|
||||
* </p>
|
||||
*/
|
||||
boolean isLocalL2Caching();
|
||||
|
||||
/**
|
||||
* Return true if there is an active bean cache for this type of bean.
|
||||
*/
|
||||
|
||||
+12
-5
@@ -20,10 +20,13 @@ public class DefaultServerCacheManager implements ServerCacheManager {
|
||||
|
||||
private final DefaultCacheHolder collectionIdsCache;
|
||||
|
||||
private final boolean localL2Caching;
|
||||
|
||||
/**
|
||||
* Create with a cache factory and default cache options.
|
||||
*/
|
||||
public DefaultServerCacheManager(ServerCacheFactory cacheFactory, ServerCacheOptions defaultBeanOptions, ServerCacheOptions defaultQueryOptions) {
|
||||
public DefaultServerCacheManager(boolean localL2Caching, ServerCacheFactory cacheFactory, ServerCacheOptions defaultBeanOptions, ServerCacheOptions defaultQueryOptions) {
|
||||
this.localL2Caching = localL2Caching;
|
||||
this.beanCache = new DefaultCacheHolder(cacheFactory, defaultBeanOptions);
|
||||
this.queryCache = new DefaultCacheHolder(cacheFactory, defaultQueryOptions);
|
||||
this.naturalKeyCache = new DefaultCacheHolder(cacheFactory, defaultBeanOptions);
|
||||
@@ -34,7 +37,11 @@ public class DefaultServerCacheManager implements ServerCacheManager {
|
||||
* Construct when l2 cache is disabled.
|
||||
*/
|
||||
public DefaultServerCacheManager() {
|
||||
this(new DefaultServerCacheFactory(), new ServerCacheOptions(), new ServerCacheOptions());
|
||||
this(true, new DefaultServerCacheFactory(), new ServerCacheOptions(), new ServerCacheOptions());
|
||||
}
|
||||
|
||||
public boolean isLocalL2Caching() {
|
||||
return localL2Caching;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,7 +56,9 @@ public class DefaultServerCacheManager implements ServerCacheManager {
|
||||
queryCache.clearCache(beanName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear all caches.
|
||||
*/
|
||||
public void clearAll() {
|
||||
beanCache.clearAll();
|
||||
queryCache.clearAll();
|
||||
@@ -57,7 +66,6 @@ public class DefaultServerCacheManager implements ServerCacheManager {
|
||||
collectionIdsCache.clearAll();
|
||||
}
|
||||
|
||||
|
||||
public ServerCache getCollectionIdsCache(Class<?> beanType, String propertyName) {
|
||||
return collectionIdsCache.getCache(beanType.getName() + "." + propertyName, ServerCacheType.COLLECTION_IDS);
|
||||
}
|
||||
@@ -87,5 +95,4 @@ public class DefaultServerCacheManager implements ServerCacheManager {
|
||||
return beanCache.isCaching(beanType.getName());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -170,6 +170,7 @@ public class DefaultContainer implements SpiContainer {
|
||||
queryOptions.setMaxIdleSecs(serverConfig.getQueryCacheMaxIdleTime());
|
||||
queryOptions.setMaxSecsToLive(serverConfig.getQueryCacheMaxTimeToLive());
|
||||
|
||||
boolean localL2Caching = false;
|
||||
ServerCachePlugin plugin = serverConfig.getServerCachePlugin();
|
||||
if (plugin == null) {
|
||||
ServiceLoader<ServerCachePlugin> cacheFactories = ServiceLoader.load(ServerCachePlugin.class);
|
||||
@@ -179,13 +180,14 @@ public class DefaultContainer implements SpiContainer {
|
||||
plugin = iterator.next();
|
||||
logger.debug("using ServerCacheFactory {}", plugin.getClass());
|
||||
} else {
|
||||
// use the built in default
|
||||
// use the built in default l2 caching which is local cache based
|
||||
localL2Caching = true;
|
||||
plugin = new DefaultServerCachePlugin();
|
||||
}
|
||||
}
|
||||
|
||||
ServerCacheFactory factory = plugin.create(serverConfig, executor);
|
||||
return new DefaultServerCacheManager(factory, beanOptions, queryOptions);
|
||||
return new DefaultServerCacheManager(localL2Caching, factory, beanOptions, queryOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -194,20 +196,20 @@ public class DefaultContainer implements SpiContainer {
|
||||
*/
|
||||
private BootupClasses getBootupClasses(ServerConfig serverConfig) {
|
||||
|
||||
BootupClasses bootupClasses = getBootupClasses1(serverConfig);
|
||||
bootupClasses.addIdGenerators(serverConfig.getIdGenerators());
|
||||
bootupClasses.addPersistControllers(serverConfig.getPersistControllers());
|
||||
bootupClasses.addPostLoaders(serverConfig.getPostLoaders());
|
||||
bootupClasses.addFindControllers(serverConfig.getFindControllers());
|
||||
bootupClasses.addTransactionEventListeners(serverConfig.getTransactionEventListeners());
|
||||
bootupClasses.addPersistListeners(serverConfig.getPersistListeners());
|
||||
bootupClasses.addQueryAdapters(serverConfig.getQueryAdapters());
|
||||
bootupClasses.addServerConfigStartup(serverConfig.getServerConfigStartupListeners());
|
||||
bootupClasses.addChangeLogInstances(serverConfig);
|
||||
BootupClasses bootup = getBootupClasses1(serverConfig);
|
||||
bootup.addIdGenerators(serverConfig.getIdGenerators());
|
||||
bootup.addPersistControllers(serverConfig.getPersistControllers());
|
||||
bootup.addPostLoaders(serverConfig.getPostLoaders());
|
||||
bootup.addFindControllers(serverConfig.getFindControllers());
|
||||
bootup.addTransactionEventListeners(serverConfig.getTransactionEventListeners());
|
||||
bootup.addPersistListeners(serverConfig.getPersistListeners());
|
||||
bootup.addQueryAdapters(serverConfig.getQueryAdapters());
|
||||
bootup.addServerConfigStartup(serverConfig.getServerConfigStartupListeners());
|
||||
bootup.addChangeLogInstances(serverConfig);
|
||||
|
||||
// run any ServerConfigStartup instances
|
||||
bootupClasses.runServerConfigStartup(serverConfig);
|
||||
return bootupClasses;
|
||||
bootup.runServerConfigStartup(serverConfig);
|
||||
return bootup;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -338,15 +338,16 @@ public class InternalConfiguration {
|
||||
*/
|
||||
public TransactionManager createTransactionManager(DocStoreUpdateProcessor indexUpdateProcessor) {
|
||||
|
||||
boolean localL2 = cacheManager.isLocalL2Caching();
|
||||
if (serverConfig.isExplicitTransactionBeginMode()) {
|
||||
return new ExplicitTransactionManager(serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, beanDescriptorManager, this.getBootupClasses());
|
||||
return new ExplicitTransactionManager(localL2, serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, beanDescriptorManager, this.getBootupClasses());
|
||||
}
|
||||
|
||||
if (isAutoCommitMode()) {
|
||||
return new AutoCommitTransactionManager(serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, beanDescriptorManager, this.getBootupClasses());
|
||||
return new AutoCommitTransactionManager(localL2, serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, beanDescriptorManager, this.getBootupClasses());
|
||||
}
|
||||
|
||||
return new TransactionManager(serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, beanDescriptorManager, this.getBootupClasses());
|
||||
return new TransactionManager(localL2, serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, beanDescriptorManager, this.getBootupClasses());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -17,10 +17,10 @@ import java.sql.Connection;
|
||||
*/
|
||||
public class AutoCommitTransactionManager extends TransactionManager {
|
||||
|
||||
public AutoCommitTransactionManager(ServerConfig serverConfig, ClusterManager clusterManager, BackgroundExecutor backgroundExecutor,
|
||||
public AutoCommitTransactionManager(boolean localL2Caching, ServerConfig serverConfig, ClusterManager clusterManager, BackgroundExecutor backgroundExecutor,
|
||||
DocStoreUpdateProcessor indexUpdateProcessor, BeanDescriptorManager descMgr, BootupClasses bootupClasses) {
|
||||
|
||||
super(serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, descMgr, bootupClasses);
|
||||
super(localL2Caching, serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, descMgr, bootupClasses);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-2
@@ -17,10 +17,10 @@ import java.sql.Connection;
|
||||
*/
|
||||
public class ExplicitTransactionManager extends TransactionManager {
|
||||
|
||||
public ExplicitTransactionManager(ServerConfig serverConfig, ClusterManager clusterManager, BackgroundExecutor backgroundExecutor,
|
||||
public ExplicitTransactionManager(boolean localL2Caching, ServerConfig serverConfig, ClusterManager clusterManager, BackgroundExecutor backgroundExecutor,
|
||||
DocStoreUpdateProcessor indexUpdateProcessor, BeanDescriptorManager descMgr, BootupClasses bootupClasses) {
|
||||
|
||||
super(serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, descMgr, bootupClasses);
|
||||
super(localL2Caching, serverConfig, clusterManager, backgroundExecutor, indexUpdateProcessor, descMgr, bootupClasses);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -84,9 +84,15 @@ public final class PostCommitProcessing {
|
||||
/**
|
||||
* Notify the local part of L2 cache.
|
||||
*/
|
||||
void notifyLocalCache(boolean viewInvalidation) {
|
||||
void notifyLocalCache() {
|
||||
processTableEvents(event.getEventTables());
|
||||
cacheChanges = event.buildCacheChanges(viewInvalidation);
|
||||
if (manager.localL2Caching) {
|
||||
// process l2 cache changes in foreground
|
||||
processCacheChanges(event.buildCacheChanges(manager.viewInvalidation));
|
||||
} else {
|
||||
// collect l2 cache changes for delayed background processing
|
||||
cacheChanges = event.buildCacheChanges(manager.viewInvalidation);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,9 +154,7 @@ public final class PostCommitProcessing {
|
||||
Runnable backgroundNotify() {
|
||||
return new Runnable() {
|
||||
public void run() {
|
||||
if (cacheChanges != null) {
|
||||
manager.processViewInvalidation(cacheChanges.apply());
|
||||
}
|
||||
processCacheChanges(cacheChanges);
|
||||
localPersistListenersNotify();
|
||||
notifyCluster();
|
||||
processDocStoreUpdates();
|
||||
@@ -158,6 +162,15 @@ public final class PostCommitProcessing {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the changes to the L2 caches.
|
||||
*/
|
||||
private void processCacheChanges(CacheChangeSet cacheChanges) {
|
||||
if (cacheChanges != null) {
|
||||
manager.processViewInvalidation(cacheChanges.apply());
|
||||
}
|
||||
}
|
||||
|
||||
private void localPersistListenersNotify() {
|
||||
if (persistBeanRequests != null) {
|
||||
for (int i = 0; i < persistBeanRequests.size(); i++) {
|
||||
|
||||
@@ -105,14 +105,17 @@ public class TransactionManager {
|
||||
*/
|
||||
private final ChangeLogListener changeLogListener;
|
||||
|
||||
private final boolean viewInvalidation;
|
||||
protected final boolean localL2Caching;
|
||||
|
||||
protected final boolean viewInvalidation;
|
||||
|
||||
/**
|
||||
* Create the TransactionManager
|
||||
*/
|
||||
public TransactionManager(ServerConfig config, ClusterManager clusterManager, BackgroundExecutor backgroundExecutor, DocStoreUpdateProcessor docStoreUpdateProcessor,
|
||||
BeanDescriptorManager descMgr, BootupClasses bootupClasses) {
|
||||
public TransactionManager(boolean localL2Caching, ServerConfig config, ClusterManager clusterManager, BackgroundExecutor backgroundExecutor,
|
||||
DocStoreUpdateProcessor docStoreUpdateProcessor, BeanDescriptorManager descMgr, BootupClasses bootupClasses) {
|
||||
|
||||
this.localL2Caching = localL2Caching;
|
||||
this.persistBatch = config.getPersistBatch();
|
||||
this.persistBatchOnCascade = config.appliedPersistBatchOnCascade();
|
||||
this.beanDescriptorManager = descMgr;
|
||||
@@ -402,7 +405,7 @@ public class TransactionManager {
|
||||
}
|
||||
|
||||
PostCommitProcessing postCommit = new PostCommitProcessing(clusterManager, this, transaction);
|
||||
postCommit.notifyLocalCache(viewInvalidation);
|
||||
postCommit.notifyLocalCache();
|
||||
backgroundExecutor.execute(postCommit.backgroundNotify());
|
||||
|
||||
for (TransactionEventListener listener : transactionEventListeners) {
|
||||
@@ -427,7 +430,7 @@ public class TransactionManager {
|
||||
event.add(tableEvents);
|
||||
|
||||
PostCommitProcessing postCommit = new PostCommitProcessing(clusterManager, this, event);
|
||||
postCommit.notifyLocalCache(viewInvalidation);
|
||||
postCommit.notifyLocalCache();
|
||||
backgroundExecutor.execute(postCommit.backgroundNotify());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user