diff --git a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java index 55c75f99e..5028691e6 100644 --- a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java +++ b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java @@ -77,7 +77,9 @@ public class RedissonRegionFactory implements RegionFactory { public static final String CONFIG_PREFIX = "hibernate.cache.redisson."; public static final String REDISSON_CONFIG_PATH = CONFIG_PREFIX + "config"; - + + public static final String FALLBACK = CONFIG_PREFIX + "fallback"; + protected RedissonClient redisson; private Settings settings; @@ -175,7 +177,7 @@ public class RedissonRegionFactory implements RegionFactory { log.debug("Building entity cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, ENTITY_DEF); - return new RedissonEntityRegion(mapCache, this, metadata, settings, properties, ENTITY_DEF); + return new RedissonEntityRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, metadata, settings, properties, ENTITY_DEF); } @Override @@ -184,7 +186,7 @@ public class RedissonRegionFactory implements RegionFactory { log.debug("Building naturalId cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, NATURAL_ID_DEF); - return new RedissonNaturalIdRegion(mapCache, this, metadata, settings, properties, NATURAL_ID_DEF); + return new RedissonNaturalIdRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, metadata, settings, properties, NATURAL_ID_DEF); } @Override @@ -193,7 +195,7 @@ public class RedissonRegionFactory implements RegionFactory { log.debug("Building collection cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, COLLECTION_DEF); - return new RedissonCollectionRegion(mapCache, this, metadata, settings, properties, COLLECTION_DEF); + return new RedissonCollectionRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, metadata, settings, properties, COLLECTION_DEF); } @Override @@ -201,7 +203,7 @@ public class RedissonRegionFactory implements RegionFactory { log.debug("Building query cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, QUERY_DEF); - return new RedissonQueryRegion(mapCache, this, properties, QUERY_DEF); + return new RedissonQueryRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, properties, QUERY_DEF); } @Override @@ -209,7 +211,7 @@ public class RedissonRegionFactory implements RegionFactory { log.debug("Building timestamps cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, TIMESTAMPS_DEF); - return new RedissonTimestampsRegion(mapCache, this, properties, TIMESTAMPS_DEF); + return new RedissonTimestampsRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, properties, TIMESTAMPS_DEF); } protected RMapCache getCache(String regionName, Properties properties, String defaultKey) { diff --git a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/BaseRegion.java b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/BaseRegion.java index 9a3f17862..6ac810529 100644 --- a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/BaseRegion.java +++ b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/BaseRegion.java @@ -15,18 +15,22 @@ */ package org.redisson.hibernate.region; -import java.util.Collections; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - import org.hibernate.cache.CacheException; import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.GeneralDataRegion; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TransactionalDataRegion; +import org.redisson.api.RFuture; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; import org.redisson.hibernate.RedissonRegionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.TimeUnit; /** * @@ -35,18 +39,24 @@ import org.redisson.hibernate.RedissonRegionFactory; */ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { + private final Logger logger = LoggerFactory.getLogger(getClass()); + final RMapCache mapCache; final RegionFactory regionFactory; final CacheDataDescription metadata; + final ConnectionManager connectionManager; int ttl; int maxIdle; - - public BaseRegion(RMapCache mapCache, RegionFactory regionFactory, CacheDataDescription metadata, Properties properties, String defaultKey) { + boolean fallback; + volatile boolean fallbackMode; + + public BaseRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, CacheDataDescription metadata, Properties properties, String defaultKey) { super(); this.mapCache = mapCache; this.regionFactory = regionFactory; this.metadata = metadata; + this.connectionManager = connectionManager; String maxEntries = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.MAX_ENTRIES_SUFFIX); if (maxEntries != null) { @@ -60,6 +70,9 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { if (maxIdleTime != null) { maxIdle = Integer.valueOf(maxIdleTime); } + + String fallbackValue = (String) properties.getOrDefault(RedissonRegionFactory.FALLBACK, "false"); + fallback = Boolean.valueOf(fallbackValue); } private String getProperty(Properties properties, String name, String defaultKey, String suffix) { @@ -74,6 +87,20 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { return null; } + private void ping() { + fallbackMode = true; + connectionManager.newTimeout(t -> { + RFuture future = mapCache.isExistsAsync(); + future.onComplete((r, ex) -> { + if (ex == null) { + fallbackMode = false; + } else { + ping(); + } + }); + }, 1, TimeUnit.SECONDS); + } + @Override public boolean isTransactionAware() { // TODO Auto-generated method stub @@ -101,9 +128,17 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { @Override public boolean contains(Object key) { + if (fallbackMode) { + return false; + } try { return mapCache.containsKey(key); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return false; + } throw new CacheException(e); } } @@ -138,39 +173,71 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { // 60 seconds (normalized value) return (1 << 12) * 60000; } - + @Override public Object get(Object key) throws CacheException { + if (fallbackMode) { + return null; + } try { return mapCache.get(key); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return null; + } throw new CacheException(e); } } @Override public void put(Object key, Object value) throws CacheException { + if (fallbackMode) { + return; + } try { mapCache.fastPut(key, value, ttl, TimeUnit.MILLISECONDS, maxIdle, TimeUnit.MILLISECONDS); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return; + } throw new CacheException(e); } } @Override public void evict(Object key) throws CacheException { + if (fallbackMode) { + return; + } try { mapCache.fastRemove(key); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return; + } throw new CacheException(e); } } @Override public void evictAll() throws CacheException { + if (fallbackMode) { + return; + } try { mapCache.clear(); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return; + } throw new CacheException(e); } } diff --git a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonCollectionRegion.java b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonCollectionRegion.java index f9490271c..8340d6261 100644 --- a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonCollectionRegion.java +++ b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonCollectionRegion.java @@ -15,8 +15,6 @@ */ package org.redisson.hibernate.region; -import java.util.Properties; - import org.hibernate.cache.CacheException; import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.CollectionRegion; @@ -25,11 +23,14 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cfg.Settings; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; import org.redisson.hibernate.strategy.NonStrictReadWriteCollectionRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadOnlyCollectionRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadWriteCollectionRegionAccessStrategy; import org.redisson.hibernate.strategy.TransactionalCollectionRegionAccessStrategy; +import java.util.Properties; + /** * * @author Nikita Koksharov @@ -38,13 +39,13 @@ import org.redisson.hibernate.strategy.TransactionalCollectionRegionAccessStrate public class RedissonCollectionRegion extends BaseRegion implements CollectionRegion { private final Settings settings; - - public RedissonCollectionRegion(RMapCache mapCache, RegionFactory regionFactory, - CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey) { - super(mapCache, regionFactory, metadata, properties, defaultKey); + + public RedissonCollectionRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, + CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey) { + super(mapCache, connectionManager, regionFactory, metadata, properties, defaultKey); this.settings = settings; } - + @Override public CollectionRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException { if (accessType == AccessType.READ_ONLY) { diff --git a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonEntityRegion.java b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonEntityRegion.java index bb3a2e902..5600645a5 100644 --- a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonEntityRegion.java +++ b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonEntityRegion.java @@ -15,8 +15,6 @@ */ package org.redisson.hibernate.region; -import java.util.Properties; - import org.hibernate.cache.CacheException; import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.EntityRegion; @@ -25,11 +23,14 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cfg.Settings; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; import org.redisson.hibernate.strategy.NonStrictReadWriteEntityRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadOnlyEntityRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadWriteEntityRegionAccessStrategy; import org.redisson.hibernate.strategy.TransactionalEntityRegionAccessStrategy; +import java.util.Properties; + /** * * @author Nikita Koksharov @@ -38,13 +39,13 @@ import org.redisson.hibernate.strategy.TransactionalEntityRegionAccessStrategy; public class RedissonEntityRegion extends BaseRegion implements EntityRegion { private final Settings settings; - - public RedissonEntityRegion(RMapCache mapCache, RegionFactory regionFactory, - CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey) { - super(mapCache, regionFactory, metadata, properties, defaultKey); + + public RedissonEntityRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, + CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey) { + super(mapCache, connectionManager, regionFactory, metadata, properties, defaultKey); this.settings = settings; } - + @Override public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException { if (accessType == AccessType.READ_ONLY) { diff --git a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonNaturalIdRegion.java b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonNaturalIdRegion.java index 9deb6e3da..fc63fa5bd 100644 --- a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonNaturalIdRegion.java +++ b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonNaturalIdRegion.java @@ -15,8 +15,6 @@ */ package org.redisson.hibernate.region; -import java.util.Properties; - import org.hibernate.cache.CacheException; import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.NaturalIdRegion; @@ -25,11 +23,14 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cfg.Settings; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; import org.redisson.hibernate.strategy.NonStrictReadWriteNaturalIdRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadOnlyNaturalIdRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadWriteNaturalIdRegionAccessStrategy; import org.redisson.hibernate.strategy.TransactionalNaturalIdRegionAccessStrategy; +import java.util.Properties; + /** * * @author Nikita Koksharov @@ -38,10 +39,10 @@ import org.redisson.hibernate.strategy.TransactionalNaturalIdRegionAccessStrateg public class RedissonNaturalIdRegion extends BaseRegion implements NaturalIdRegion { private final Settings settings; - - public RedissonNaturalIdRegion(RMapCache mapCache, RegionFactory regionFactory, - CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey) { - super(mapCache, regionFactory, metadata, properties, defaultKey); + + public RedissonNaturalIdRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, + CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey) { + super(mapCache, connectionManager, regionFactory, metadata, properties, defaultKey); this.settings = settings; } diff --git a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonQueryRegion.java b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonQueryRegion.java index ddb2dd774..d47be5b88 100644 --- a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonQueryRegion.java +++ b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonQueryRegion.java @@ -20,6 +20,7 @@ import java.util.Properties; import org.hibernate.cache.spi.QueryResultsRegion; import org.hibernate.cache.spi.RegionFactory; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; /** * @@ -28,9 +29,9 @@ import org.redisson.api.RMapCache; */ public class RedissonQueryRegion extends BaseRegion implements QueryResultsRegion { - public RedissonQueryRegion(RMapCache mapCache, + public RedissonQueryRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, Properties properties, String defaultKey) { - super(mapCache, regionFactory, null, properties, defaultKey); + super(mapCache, connectionManager, regionFactory, null, properties, defaultKey); } } diff --git a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonTimestampsRegion.java b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonTimestampsRegion.java index cd5a24188..10bd08b73 100644 --- a/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonTimestampsRegion.java +++ b/redisson-hibernate/redisson-hibernate-4/src/main/java/org/redisson/hibernate/region/RedissonTimestampsRegion.java @@ -20,6 +20,7 @@ import java.util.Properties; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TimestampsRegion; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; /** * @@ -28,9 +29,9 @@ import org.redisson.api.RMapCache; */ public class RedissonTimestampsRegion extends BaseRegion implements TimestampsRegion { - public RedissonTimestampsRegion(RMapCache mapCache, + public RedissonTimestampsRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, Properties properties, String defaultKey) { - super(mapCache, regionFactory, null, properties, defaultKey); + super(mapCache, connectionManager, regionFactory, null, properties, defaultKey); } } diff --git a/redisson-hibernate/redisson-hibernate-4/src/test/java/org/redisson/hibernate/ReadWriteTest.java b/redisson-hibernate/redisson-hibernate-4/src/test/java/org/redisson/hibernate/ReadWriteTest.java index 0ff26a9c6..07852f17e 100644 --- a/redisson-hibernate/redisson-hibernate-4/src/test/java/org/redisson/hibernate/ReadWriteTest.java +++ b/redisson-hibernate/redisson-hibernate-4/src/test/java/org/redisson/hibernate/ReadWriteTest.java @@ -31,7 +31,7 @@ public class ReadWriteTest extends BaseCoreFunctionalTestCase { protected void configure(Configuration cfg) { super.configure(cfg); cfg.setProperty(Environment.DRIVER, org.h2.Driver.class.getName()); - cfg.setProperty(Environment.URL, "jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE"); + cfg.setProperty(Environment.URL, "jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1"); cfg.setProperty(Environment.USER, "sa"); cfg.setProperty(Environment.PASS, ""); cfg.setProperty(Environment.CACHE_REGION_PREFIX, ""); diff --git a/redisson-hibernate/redisson-hibernate-4/src/test/java/org/redisson/hibernate/TransactionalTest.java b/redisson-hibernate/redisson-hibernate-4/src/test/java/org/redisson/hibernate/TransactionalTest.java index 3b346a459..5fa50c216 100644 --- a/redisson-hibernate/redisson-hibernate-4/src/test/java/org/redisson/hibernate/TransactionalTest.java +++ b/redisson-hibernate/redisson-hibernate-4/src/test/java/org/redisson/hibernate/TransactionalTest.java @@ -31,7 +31,7 @@ public class TransactionalTest extends BaseCoreFunctionalTestCase { protected void configure(Configuration cfg) { super.configure(cfg); cfg.setProperty(Environment.DRIVER, org.h2.Driver.class.getName()); - cfg.setProperty(Environment.URL, "jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE"); + cfg.setProperty(Environment.URL, "jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1"); cfg.setProperty(Environment.USER, "sa"); cfg.setProperty(Environment.PASS, ""); cfg.setProperty(Environment.CACHE_REGION_PREFIX, ""); diff --git a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java index a32e43e96..8532263b7 100644 --- a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java +++ b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java @@ -69,7 +69,9 @@ import java.util.Properties; public static final String CONFIG_PREFIX = "hibernate.cache.redisson."; public static final String REDISSON_CONFIG_PATH = CONFIG_PREFIX + "config"; - + + public static final String FALLBACK = CONFIG_PREFIX + "fallback"; + protected RedissonClient redisson; private Settings settings; private CacheKeysFactory cacheKeysFactory; @@ -173,7 +175,7 @@ import java.util.Properties; log.debug("Building entity cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, ENTITY_DEF); - return new RedissonEntityRegion(mapCache, this, metadata, settings, properties, ENTITY_DEF, cacheKeysFactory); + return new RedissonEntityRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, metadata, settings, properties, ENTITY_DEF, cacheKeysFactory); } @Override @@ -182,7 +184,7 @@ import java.util.Properties; log.debug("Building naturalId cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, NATURAL_ID_DEF); - return new RedissonNaturalIdRegion(mapCache, this, metadata, settings, properties, NATURAL_ID_DEF, cacheKeysFactory); + return new RedissonNaturalIdRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, metadata, settings, properties, NATURAL_ID_DEF, cacheKeysFactory); } @Override @@ -191,7 +193,7 @@ import java.util.Properties; log.debug("Building collection cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, COLLECTION_DEF); - return new RedissonCollectionRegion(mapCache, this, metadata, settings, properties, COLLECTION_DEF, cacheKeysFactory); + return new RedissonCollectionRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, metadata, settings, properties, COLLECTION_DEF, cacheKeysFactory); } @Override @@ -199,7 +201,7 @@ import java.util.Properties; log.debug("Building query cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, QUERY_DEF); - return new RedissonQueryRegion(mapCache, this, properties, QUERY_DEF); + return new RedissonQueryRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, properties, QUERY_DEF); } @Override @@ -207,7 +209,7 @@ import java.util.Properties; log.debug("Building timestamps cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, TIMESTAMPS_DEF); - return new RedissonTimestampsRegion(mapCache, this, properties, TIMESTAMPS_DEF); + return new RedissonTimestampsRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, properties, TIMESTAMPS_DEF); } protected RMapCache getCache(String regionName, Properties properties, String defaultKey) { diff --git a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/BaseRegion.java b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/BaseRegion.java index ac1857f8b..510966828 100644 --- a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/BaseRegion.java +++ b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/BaseRegion.java @@ -15,19 +15,23 @@ */ package org.redisson.hibernate.region; -import java.util.Collections; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - import org.hibernate.cache.CacheException; import org.hibernate.cache.spi.CacheDataDescription; import org.hibernate.cache.spi.GeneralDataRegion; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TransactionalDataRegion; import org.hibernate.engine.spi.SessionImplementor; +import org.redisson.api.RFuture; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; import org.redisson.hibernate.RedissonRegionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.TimeUnit; /** * @@ -36,18 +40,24 @@ import org.redisson.hibernate.RedissonRegionFactory; */ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { + private final Logger logger = LoggerFactory.getLogger(getClass()); + final RMapCache mapCache; final RegionFactory regionFactory; final CacheDataDescription metadata; + final ConnectionManager connectionManager; int ttl; int maxIdle; - - public BaseRegion(RMapCache mapCache, RegionFactory regionFactory, CacheDataDescription metadata, Properties properties, String defaultKey) { + boolean fallback; + volatile boolean fallbackMode; + + public BaseRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, CacheDataDescription metadata, Properties properties, String defaultKey) { super(); this.mapCache = mapCache; this.regionFactory = regionFactory; this.metadata = metadata; + this.connectionManager = connectionManager; String maxEntries = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.MAX_ENTRIES_SUFFIX); if (maxEntries != null) { @@ -61,6 +71,9 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { if (maxIdleTime != null) { maxIdle = Integer.valueOf(maxIdleTime); } + + String fallbackValue = (String) properties.getOrDefault(RedissonRegionFactory.FALLBACK, "false"); + fallback = Boolean.valueOf(fallbackValue); } private String getProperty(Properties properties, String name, String defaultKey, String suffix) { @@ -75,6 +88,20 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { return null; } + private void ping() { + fallbackMode = true; + connectionManager.newTimeout(t -> { + RFuture future = mapCache.isExistsAsync(); + future.onComplete((r, ex) -> { + if (ex == null) { + fallbackMode = false; + } else { + ping(); + } + }); + }, 1, TimeUnit.SECONDS); + } + @Override public boolean isTransactionAware() { // TODO Auto-generated method stub @@ -102,9 +129,17 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { @Override public boolean contains(Object key) { + if (fallbackMode) { + return false; + } try { return mapCache.containsKey(key); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return false; + } throw new CacheException(e); } } @@ -142,36 +177,68 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { @Override public Object get(SessionImplementor session, Object key) throws CacheException { + if (fallbackMode) { + return null; + } try { return mapCache.get(key); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return null; + } throw new CacheException(e); } } @Override public void put(SessionImplementor session, Object key, Object value) throws CacheException { + if (fallbackMode) { + return; + } try { mapCache.fastPut(key, value, ttl, TimeUnit.MILLISECONDS, maxIdle, TimeUnit.MILLISECONDS); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return; + } throw new CacheException(e); } } @Override public void evict(Object key) throws CacheException { + if (fallbackMode) { + return; + } try { mapCache.fastRemove(key); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return; + } throw new CacheException(e); } } @Override public void evictAll() throws CacheException { + if (fallbackMode) { + return; + } try { mapCache.clear(); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return; + } throw new CacheException(e); } } diff --git a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonCollectionRegion.java b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonCollectionRegion.java index 60a9b2a8a..9c86a35d7 100644 --- a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonCollectionRegion.java +++ b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonCollectionRegion.java @@ -26,6 +26,7 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cfg.Settings; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; import org.redisson.hibernate.strategy.NonStrictReadWriteCollectionRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadOnlyCollectionRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadWriteCollectionRegionAccessStrategy; @@ -41,13 +42,13 @@ public class RedissonCollectionRegion extends BaseRegion implements CollectionRe private final Settings settings; private final CacheKeysFactory cacheKeysFactory; - public RedissonCollectionRegion(RMapCache mapCache, RegionFactory regionFactory, - CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) { - super(mapCache, regionFactory, metadata, properties, defaultKey); + public RedissonCollectionRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, + CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) { + super(mapCache, connectionManager, regionFactory, metadata, properties, defaultKey); this.settings = settings; this.cacheKeysFactory = cacheKeysFactory; } - + public CacheKeysFactory getCacheKeysFactory() { return cacheKeysFactory; } diff --git a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonEntityRegion.java b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonEntityRegion.java index b97744425..1ca997a4f 100644 --- a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonEntityRegion.java +++ b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonEntityRegion.java @@ -26,6 +26,7 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cfg.Settings; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; import org.redisson.hibernate.strategy.NonStrictReadWriteEntityRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadOnlyEntityRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadWriteEntityRegionAccessStrategy; @@ -41,13 +42,13 @@ public class RedissonEntityRegion extends BaseRegion implements EntityRegion { private final Settings settings; private final CacheKeysFactory cacheKeysFactory; - public RedissonEntityRegion(RMapCache mapCache, RegionFactory regionFactory, - CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) { - super(mapCache, regionFactory, metadata, properties, defaultKey); + public RedissonEntityRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, + CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) { + super(mapCache, connectionManager, regionFactory, metadata, properties, defaultKey); this.settings = settings; this.cacheKeysFactory = cacheKeysFactory; } - + public CacheKeysFactory getCacheKeysFactory() { return cacheKeysFactory; } diff --git a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonNaturalIdRegion.java b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonNaturalIdRegion.java index 5f71c8b65..b5deabbc5 100644 --- a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonNaturalIdRegion.java +++ b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonNaturalIdRegion.java @@ -26,6 +26,7 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cfg.Settings; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; import org.redisson.hibernate.strategy.NonStrictReadWriteNaturalIdRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadOnlyNaturalIdRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadWriteNaturalIdRegionAccessStrategy; @@ -41,9 +42,9 @@ public class RedissonNaturalIdRegion extends BaseRegion implements NaturalIdRegi private final Settings settings; private final CacheKeysFactory cacheKeysFactory; - public RedissonNaturalIdRegion(RMapCache mapCache, RegionFactory regionFactory, - CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) { - super(mapCache, regionFactory, metadata, properties, defaultKey); + public RedissonNaturalIdRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, + CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) { + super(mapCache, connectionManager, regionFactory, metadata, properties, defaultKey); this.settings = settings; this.cacheKeysFactory = cacheKeysFactory; } @@ -51,7 +52,7 @@ public class RedissonNaturalIdRegion extends BaseRegion implements NaturalIdRegi public CacheKeysFactory getCacheKeysFactory() { return cacheKeysFactory; } - + @Override public NaturalIdRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException { if (accessType == AccessType.READ_ONLY) { diff --git a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonQueryRegion.java b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonQueryRegion.java index ddb2dd774..d47be5b88 100644 --- a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonQueryRegion.java +++ b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonQueryRegion.java @@ -20,6 +20,7 @@ import java.util.Properties; import org.hibernate.cache.spi.QueryResultsRegion; import org.hibernate.cache.spi.RegionFactory; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; /** * @@ -28,9 +29,9 @@ import org.redisson.api.RMapCache; */ public class RedissonQueryRegion extends BaseRegion implements QueryResultsRegion { - public RedissonQueryRegion(RMapCache mapCache, + public RedissonQueryRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, Properties properties, String defaultKey) { - super(mapCache, regionFactory, null, properties, defaultKey); + super(mapCache, connectionManager, regionFactory, null, properties, defaultKey); } } diff --git a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonTimestampsRegion.java b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonTimestampsRegion.java index cd5a24188..10bd08b73 100644 --- a/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonTimestampsRegion.java +++ b/redisson-hibernate/redisson-hibernate-5/src/main/java/org/redisson/hibernate/region/RedissonTimestampsRegion.java @@ -20,6 +20,7 @@ import java.util.Properties; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TimestampsRegion; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; /** * @@ -28,9 +29,9 @@ import org.redisson.api.RMapCache; */ public class RedissonTimestampsRegion extends BaseRegion implements TimestampsRegion { - public RedissonTimestampsRegion(RMapCache mapCache, + public RedissonTimestampsRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, Properties properties, String defaultKey) { - super(mapCache, regionFactory, null, properties, defaultKey); + super(mapCache, connectionManager, regionFactory, null, properties, defaultKey); } } diff --git a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java index 22064d184..9e805657f 100644 --- a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java +++ b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java @@ -70,6 +70,8 @@ public class RedissonRegionFactory implements RegionFactory { public static final String CONFIG_PREFIX = "hibernate.cache.redisson."; public static final String REDISSON_CONFIG_PATH = CONFIG_PREFIX + "config"; + + public static final String FALLBACK = CONFIG_PREFIX + "fallback"; protected RedissonClient redisson; private Settings settings; @@ -173,7 +175,7 @@ public class RedissonRegionFactory implements RegionFactory { log.debug("Building entity cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, ENTITY_DEF); - return new RedissonEntityRegion(mapCache, this, metadata, settings, properties, ENTITY_DEF, cacheKeysFactory); + return new RedissonEntityRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, metadata, settings, properties, ENTITY_DEF, cacheKeysFactory); } @Override @@ -182,7 +184,7 @@ public class RedissonRegionFactory implements RegionFactory { log.debug("Building naturalId cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, NATURAL_ID_DEF); - return new RedissonNaturalIdRegion(mapCache, this, metadata, settings, properties, NATURAL_ID_DEF, cacheKeysFactory); + return new RedissonNaturalIdRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, metadata, settings, properties, NATURAL_ID_DEF, cacheKeysFactory); } @Override @@ -191,7 +193,7 @@ public class RedissonRegionFactory implements RegionFactory { log.debug("Building collection cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, COLLECTION_DEF); - return new RedissonCollectionRegion(mapCache, this, metadata, settings, properties, COLLECTION_DEF, cacheKeysFactory); + return new RedissonCollectionRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, metadata, settings, properties, COLLECTION_DEF, cacheKeysFactory); } @Override @@ -199,7 +201,7 @@ public class RedissonRegionFactory implements RegionFactory { log.debug("Building query cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, QUERY_DEF); - return new RedissonQueryRegion(mapCache, this, properties, QUERY_DEF); + return new RedissonQueryRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, properties, QUERY_DEF); } @Override @@ -207,7 +209,7 @@ public class RedissonRegionFactory implements RegionFactory { log.debug("Building timestamps cache region: " + regionName); RMapCache mapCache = getCache(regionName, properties, TIMESTAMPS_DEF); - return new RedissonTimestampsRegion(mapCache, this, properties, TIMESTAMPS_DEF); + return new RedissonTimestampsRegion(mapCache, ((Redisson)redisson).getConnectionManager(),this, properties, TIMESTAMPS_DEF); } protected RMapCache getCache(String regionName, Properties properties, String defaultKey) { diff --git a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/BaseRegion.java b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/BaseRegion.java index 9fe5ecab3..a54844d33 100644 --- a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/BaseRegion.java +++ b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/BaseRegion.java @@ -26,8 +26,12 @@ import org.hibernate.cache.spi.GeneralDataRegion; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TransactionalDataRegion; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.redisson.api.RFuture; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; import org.redisson.hibernate.RedissonRegionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @@ -36,18 +40,24 @@ import org.redisson.hibernate.RedissonRegionFactory; */ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { + private final Logger logger = LoggerFactory.getLogger(getClass()); + final RMapCache mapCache; final RegionFactory regionFactory; final CacheDataDescription metadata; + final ConnectionManager connectionManager; int ttl; int maxIdle; - - public BaseRegion(RMapCache mapCache, RegionFactory regionFactory, CacheDataDescription metadata, Properties properties, String defaultKey) { + boolean fallback; + volatile boolean fallbackMode; + + public BaseRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, CacheDataDescription metadata, Properties properties, String defaultKey) { super(); this.mapCache = mapCache; this.regionFactory = regionFactory; this.metadata = metadata; + this.connectionManager = connectionManager; String maxEntries = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.MAX_ENTRIES_SUFFIX); if (maxEntries != null) { @@ -61,6 +71,9 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { if (maxIdleTime != null) { maxIdle = Integer.valueOf(maxIdleTime); } + + String fallbackValue = (String) properties.getOrDefault(RedissonRegionFactory.FALLBACK, "false"); + fallback = Boolean.valueOf(fallbackValue); } private String getProperty(Properties properties, String name, String defaultKey, String suffix) { @@ -75,6 +88,20 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { return null; } + private void ping() { + fallbackMode = true; + connectionManager.newTimeout(t -> { + RFuture future = mapCache.isExistsAsync(); + future.onComplete((r, ex) -> { + if (ex == null) { + fallbackMode = false; + } else { + ping(); + } + }); + }, 1, TimeUnit.SECONDS); + } + @Override public boolean isTransactionAware() { // TODO Auto-generated method stub @@ -102,9 +129,17 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { @Override public boolean contains(Object key) { + if (fallbackMode) { + return false; + } try { return mapCache.containsKey(key); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return false; + } throw new CacheException(e); } } @@ -142,36 +177,68 @@ public class BaseRegion implements TransactionalDataRegion, GeneralDataRegion { @Override public Object get(SharedSessionContractImplementor session, Object key) throws CacheException { + if (fallbackMode) { + return null; + } try { return mapCache.get(key); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return null; + } throw new CacheException(e); } } @Override public void put(SharedSessionContractImplementor session, Object key, Object value) throws CacheException { + if (fallbackMode) { + return; + } try { mapCache.fastPut(key, value, ttl, TimeUnit.MILLISECONDS, maxIdle, TimeUnit.MILLISECONDS); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return; + } throw new CacheException(e); } } @Override public void evict(Object key) throws CacheException { + if (fallbackMode) { + return; + } try { mapCache.fastRemove(key); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return; + } throw new CacheException(e); } } @Override public void evictAll() throws CacheException { + if (fallbackMode) { + return; + } try { mapCache.clear(); } catch (Exception e) { + if (fallback) { + ping(); + logger.error(e.getMessage(), e); + return; + } throw new CacheException(e); } } diff --git a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonCollectionRegion.java b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonCollectionRegion.java index 2029852ce..9c86a35d7 100644 --- a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonCollectionRegion.java +++ b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonCollectionRegion.java @@ -26,6 +26,7 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.CollectionRegionAccessStrategy; import org.hibernate.cfg.Settings; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; import org.redisson.hibernate.strategy.NonStrictReadWriteCollectionRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadOnlyCollectionRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadWriteCollectionRegionAccessStrategy; @@ -41,9 +42,9 @@ public class RedissonCollectionRegion extends BaseRegion implements CollectionRe private final Settings settings; private final CacheKeysFactory cacheKeysFactory; - public RedissonCollectionRegion(RMapCache mapCache, RegionFactory regionFactory, - CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) { - super(mapCache, regionFactory, metadata, properties, defaultKey); + public RedissonCollectionRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, + CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) { + super(mapCache, connectionManager, regionFactory, metadata, properties, defaultKey); this.settings = settings; this.cacheKeysFactory = cacheKeysFactory; } diff --git a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonEntityRegion.java b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonEntityRegion.java index 2c103abc5..1ca997a4f 100644 --- a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonEntityRegion.java +++ b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonEntityRegion.java @@ -26,6 +26,7 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cfg.Settings; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; import org.redisson.hibernate.strategy.NonStrictReadWriteEntityRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadOnlyEntityRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadWriteEntityRegionAccessStrategy; @@ -41,9 +42,9 @@ public class RedissonEntityRegion extends BaseRegion implements EntityRegion { private final Settings settings; private final CacheKeysFactory cacheKeysFactory; - public RedissonEntityRegion(RMapCache mapCache, RegionFactory regionFactory, - CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) { - super(mapCache, regionFactory, metadata, properties, defaultKey); + public RedissonEntityRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, + CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) { + super(mapCache, connectionManager, regionFactory, metadata, properties, defaultKey); this.settings = settings; this.cacheKeysFactory = cacheKeysFactory; } diff --git a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonNaturalIdRegion.java b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonNaturalIdRegion.java index caba1043e..b5deabbc5 100644 --- a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonNaturalIdRegion.java +++ b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonNaturalIdRegion.java @@ -26,6 +26,7 @@ import org.hibernate.cache.spi.access.AccessType; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.cfg.Settings; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; import org.redisson.hibernate.strategy.NonStrictReadWriteNaturalIdRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadOnlyNaturalIdRegionAccessStrategy; import org.redisson.hibernate.strategy.ReadWriteNaturalIdRegionAccessStrategy; @@ -41,9 +42,9 @@ public class RedissonNaturalIdRegion extends BaseRegion implements NaturalIdRegi private final Settings settings; private final CacheKeysFactory cacheKeysFactory; - public RedissonNaturalIdRegion(RMapCache mapCache, RegionFactory regionFactory, - CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) { - super(mapCache, regionFactory, metadata, properties, defaultKey); + public RedissonNaturalIdRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, + CacheDataDescription metadata, Settings settings, Properties properties, String defaultKey, CacheKeysFactory cacheKeysFactory) { + super(mapCache, connectionManager, regionFactory, metadata, properties, defaultKey); this.settings = settings; this.cacheKeysFactory = cacheKeysFactory; } diff --git a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonQueryRegion.java b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonQueryRegion.java index ddb2dd774..d47be5b88 100644 --- a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonQueryRegion.java +++ b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonQueryRegion.java @@ -20,6 +20,7 @@ import java.util.Properties; import org.hibernate.cache.spi.QueryResultsRegion; import org.hibernate.cache.spi.RegionFactory; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; /** * @@ -28,9 +29,9 @@ import org.redisson.api.RMapCache; */ public class RedissonQueryRegion extends BaseRegion implements QueryResultsRegion { - public RedissonQueryRegion(RMapCache mapCache, + public RedissonQueryRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, Properties properties, String defaultKey) { - super(mapCache, regionFactory, null, properties, defaultKey); + super(mapCache, connectionManager, regionFactory, null, properties, defaultKey); } } diff --git a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonTimestampsRegion.java b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonTimestampsRegion.java index cd5a24188..10bd08b73 100644 --- a/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonTimestampsRegion.java +++ b/redisson-hibernate/redisson-hibernate-52/src/main/java/org/redisson/hibernate/region/RedissonTimestampsRegion.java @@ -20,6 +20,7 @@ import java.util.Properties; import org.hibernate.cache.spi.RegionFactory; import org.hibernate.cache.spi.TimestampsRegion; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; /** * @@ -28,9 +29,9 @@ import org.redisson.api.RMapCache; */ public class RedissonTimestampsRegion extends BaseRegion implements TimestampsRegion { - public RedissonTimestampsRegion(RMapCache mapCache, + public RedissonTimestampsRegion(RMapCache mapCache, ConnectionManager connectionManager, RegionFactory regionFactory, Properties properties, String defaultKey) { - super(mapCache, regionFactory, null, properties, defaultKey); + super(mapCache, connectionManager, regionFactory, null, properties, defaultKey); } } diff --git a/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java b/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java index f29e79a69..43688c810 100644 --- a/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java +++ b/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/RedissonRegionFactory.java @@ -115,7 +115,6 @@ public class RedissonRegionFactory extends RegionFactoryTemplate { String fallbackValue = (String) properties.getOrDefault(FALLBACK, "false"); fallback = Boolean.valueOf(fallbackValue); - return Redisson.create(config); } @@ -215,21 +214,21 @@ public class RedissonRegionFactory extends RegionFactoryTemplate { } RMapCache mapCache = getCache(regionConfig.getRegionName(), buildingContext.getSessionFactory().getProperties(), defaultKey); - return new RedissonStorage(mapCache, buildingContext.getSessionFactory().getProperties(), defaultKey); + return new RedissonStorage(mapCache, ((Redisson)redisson).getConnectionManager(), buildingContext.getSessionFactory().getProperties(), defaultKey); } @Override protected StorageAccess createQueryResultsRegionStorageAccess(String regionName, SessionFactoryImplementor sessionFactory) { RMapCache mapCache = getCache(regionName, sessionFactory.getProperties(), QUERY_DEF); - return new RedissonStorage(mapCache, sessionFactory.getProperties(), QUERY_DEF); + return new RedissonStorage(mapCache, ((Redisson)redisson).getConnectionManager(), sessionFactory.getProperties(), QUERY_DEF); } @Override protected StorageAccess createTimestampsRegionStorageAccess(String regionName, SessionFactoryImplementor sessionFactory) { RMapCache mapCache = getCache(regionName, sessionFactory.getProperties(), TIMESTAMPS_DEF); - return new RedissonStorage(mapCache, sessionFactory.getProperties(), TIMESTAMPS_DEF); + return new RedissonStorage(mapCache, ((Redisson)redisson).getConnectionManager(), sessionFactory.getProperties(), TIMESTAMPS_DEF); } protected RMapCache getCache(String regionName, Map properties, String defaultKey) { diff --git a/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/RedissonStorage.java b/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/RedissonStorage.java index 6fa9ca1f9..3f23c7d9b 100644 --- a/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/RedissonStorage.java +++ b/redisson-hibernate/redisson-hibernate-53/src/main/java/org/redisson/hibernate/RedissonStorage.java @@ -15,16 +15,18 @@ */ package org.redisson.hibernate; -import java.util.Map; -import java.util.concurrent.TimeUnit; - import org.hibernate.cache.CacheException; import org.hibernate.cache.spi.support.DomainDataStorageAccess; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.redisson.api.RFuture; import org.redisson.api.RMapCache; +import org.redisson.connection.ConnectionManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Map; +import java.util.concurrent.TimeUnit; + /** * * @author Nikita Koksharov @@ -35,14 +37,18 @@ public class RedissonStorage implements DomainDataStorageAccess { private static final Logger logger = LoggerFactory.getLogger(RedissonStorage.class); private final RMapCache mapCache; - + + private final ConnectionManager connectionManager; + int ttl; int maxIdle; boolean fallback; + volatile boolean fallbackMode; - public RedissonStorage(RMapCache mapCache, Map properties, String defaultKey) { + public RedissonStorage(RMapCache mapCache, ConnectionManager connectionManager, Map properties, String defaultKey) { super(); this.mapCache = mapCache; + this.connectionManager = connectionManager; String maxEntries = getProperty(properties, mapCache.getName(), defaultKey, RedissonRegionFactory.MAX_ENTRIES_SUFFIX); if (maxEntries != null) { @@ -73,12 +79,30 @@ public class RedissonStorage implements DomainDataStorageAccess { return null; } + private void ping() { + fallbackMode = true; + connectionManager.newTimeout(t -> { + RFuture future = mapCache.isExistsAsync(); + future.onComplete((r, ex) -> { + if (ex == null) { + fallbackMode = false; + } else { + ping(); + } + }); + }, 1, TimeUnit.SECONDS); + } + @Override public Object getFromCache(Object key, SharedSessionContractImplementor session) { + if (fallbackMode) { + return null; + } try { return mapCache.get(key); } catch (Exception e) { if (fallback) { + ping(); logger.error(e.getMessage(), e); return null; } @@ -88,10 +112,14 @@ public class RedissonStorage implements DomainDataStorageAccess { @Override public void putIntoCache(Object key, Object value, SharedSessionContractImplementor session) { + if (fallbackMode) { + return; + } try { mapCache.fastPut(key, value, ttl, TimeUnit.MILLISECONDS, maxIdle, TimeUnit.MILLISECONDS); } catch (Exception e) { if (fallback) { + ping(); logger.error(e.getMessage(), e); return; } @@ -101,10 +129,14 @@ public class RedissonStorage implements DomainDataStorageAccess { @Override public boolean contains(Object key) { + if (fallbackMode) { + return false; + } try { return mapCache.containsKey(key); } catch (Exception e) { if (fallback) { + ping(); logger.error(e.getMessage(), e); return false; } @@ -114,10 +146,14 @@ public class RedissonStorage implements DomainDataStorageAccess { @Override public void evictData() { + if (fallbackMode) { + return; + } try { mapCache.clear(); } catch (Exception e) { if (fallback) { + ping(); logger.error(e.getMessage(), e); return; } @@ -127,10 +163,14 @@ public class RedissonStorage implements DomainDataStorageAccess { @Override public void evictData(Object key) { + if (fallbackMode) { + return; + } try { mapCache.fastRemove(key); } catch (Exception e) { if (fallback) { + ping(); logger.error(e.getMessage(), e); return; } @@ -143,10 +183,6 @@ public class RedissonStorage implements DomainDataStorageAccess { try { mapCache.destroy(); } catch (Exception e) { - if (fallback) { - logger.error(e.getMessage(), e); - return; - } throw new CacheException(e); } }