如果标记的方法@Cacheable需要10分钟才能完成,并且两个线程t1,t2访问该方法.
t1访问时间0(缓存方法现在第一次运行)t2访问在时间t1 + 5mins
这是否意味着t2将不会访问数据大约5分钟,因为t1已经开始@Cacheable操作并且它将在5分钟内完成(因为它已运行5分钟)或者是否会@Cacheable被t2调用新的调用?
使用Spring的缓存抽象,如何在仍然返回旧条目的同时异步刷新条目?
我正在尝试使用Spring的缓存抽象来创建一个缓存系统,在相对较短的"软"超时之后,缓存条目可以进行刷新.然后,在查询它们时,返回缓存的值,并启动异步更新操作以刷新条目.我也会
Guava的缓存构建器允许我指定缓存中的条目应在一定时间后刷新.然后可以使用异步实现覆盖缓存加载器的reload()方法,允许返回过时的缓存值,直到检索到新的缓存值.但是,spring缓存似乎不使用底层Guava缓存的CacheLoader
是否可以使用Spring的缓存抽象来进行这种异步缓存刷新?
编辑澄清:使用Guava的CacheBuilder,我可以使用refreshAfterWrite()来获取我想要的行为.例如来自Guava Caches解释:
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
.maximumSize(1000)
.refreshAfterWrite(1, TimeUnit.MINUTES)
.build(
new CacheLoader<Key, Graph>() {
public Graph load(Key key) { // no checked exception
return getGraphFromDatabase(key);
}
public ListenableFuture<Graph> reload(final Key key, Graph prevGraph) {
if (neverNeedsRefresh(key)) {
return Futures.immediateFuture(prevGraph);
} else {
// asynchronous!
ListenableFutureTask<Graph> task = ListenableFutureTask.create(new Callable<Graph>() {
public Graph call() {
return getGraphFromDatabase(key);
}
});
executor.execute(task);
return task;
}
}
});
Run Code Online (Sandbox Code Playgroud)
但是,我看不到使用Spring的@Cacheable抽象来获取refreshAfterWrite()行为的方法.
我的弹簧启动项目配置如下.
@SpringBootApplication
@EnableTransactionManagement
@EnableCaching
@EnableScheduling
@EnableAsync
public class Application {
String redisHost = "localhost";
int redisPort = 6379;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(redisHost);
factory.setPort(redisPort);
factory.setUsePool(true);
return factory;
}
@Bean
RedisTemplate<Object, Object> redisTemplate() {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
redisTemplate.setConnectionFactory(jedisConnectionFactory());
return redisTemplate;
}
@Bean
public CacheManager cacheManager() {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate());
return cacheManager;
}
}
Run Code Online (Sandbox Code Playgroud)
我也跟随maven对pom的依赖.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)
我在定义端口上的本地计算机上运行了一个单独的redis服务器.另外在我的服务类中,我有@Cacheable,@ CachePut等注释来支持缓存.
我可以毫无错误地启动Spring启动应用程序,并且CRUD操作也可以.但似乎它没有使用定义的redis缓存.我使用'redi …
我试图将缓存添加到CRUD应用程序,我开始执行以下操作:
@Cacheable("users")
List<User> list() {
return userRepository.findAll()
}
@CachePut(value = "users", key = "#user.id")
void create(User user) {
userRepository.create(user)
}
@CachePut(value = "users", key = "#user.id")
void update(User user) {
userRepository.update(user)
}
@CacheEvict(value = "users", key = "#user.id")
void delete(User user) {
userRepository.delete(user)
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我希望create / update / delete操作可以为该操作更新已存储在缓存中的元素list()(请注意,list()不是从数据库中拉出而是从数据引擎中拉出),但是我无法做到这一点。
我想缓存list()单独返回的所有元素,以便所有其他操作可以使用来更新缓存#user.id。或者,可能需要执行所有操作来更新已存储在缓存中的列表。
我读到我可以在更新整个缓存时逐出整个缓存,但是我想避免这样的事情:
@CacheEvict(value = "users", allEntries=true)
void create(User user) {
userRepository.create(user)
}
Run Code Online (Sandbox Code Playgroud)
有什么方法可以在缓存的集合中创建/更新/删除值?还是将集合中的所有值作为单独的键缓存?
我想要动态缓存名称,spring 4.1 允许这样做
从 Spring 4.1 开始,缓存注释的 value 属性不再是强制性的,因为无论注释的内容如何,CacheResolver 都可以提供此特定信息。
请注意我如何偏执地设置cacheResolver所有可能的级别:
@Cacheable(cacheResolver = "defaultCacheResolver")
@CacheConfig(cacheResolver = "defaultCacheResolver")
public interface GatewayRepository extends CrudRepository<Gateway, Integer> {
@Cacheable(cacheResolver = "defaultCacheResolver")
Gateway findByBulkId(int bulkId);
}
Run Code Online (Sandbox Code Playgroud)
Spring 4.1.5 仍然无法验证配置并出现错误:Caused by: java.lang.IllegalStateException: No cache names could be detected on 'public abstract skunkworks.data.Gateway skunkworks.repos.GatewayRepository.findByBulkId(int)'. Make sure to set the value parameter on the annotation or declare a @CacheConfig at the class-level with the default cache name(s) to use.
at org.springframework.cache.annotation.SpringCacheAnnotationParser.validateCacheOperation(SpringCacheAnnotationParser.java:240)
我正在使用ThreadSafeList,因为它将数据从进程流式传输到Web服务器,然后在将数据传入客户端时将数据流回流,因此我获得了很大的收益.在内存中我使用Spring Caching(引擎盖下的ehcache)将数据保存在JVM中,一切都很顺利.当我开始达到我的堆限制并且Spring Caching在我使用它时将我的ThreadSafeList序列化到磁盘时,麻烦就开始了,导致了ConcurrentModificationExceptions.我可以覆盖Serialization接口的私有writeObject和readObject方法来解决问题吗?我不确定如何做到这一点或我是否应该放弃我的ThreadSafeList.
回到我开始这个程序的时候,我使用的是BlockingDeque,但这还不够,因为当我放置并采用结构时,我记不起用于缓存的数据......我不能使用ConcurrentMap因为我需要订购在我的列表中...我应该去ConcurrentNavigableMap吗?我想用ThreadSafeList滚动自己,自定义私有序列化功能可能是浪费?
java multithreading java.util.concurrent concurrentmodification spring-cache
考虑一个可以插入和检索对象并使用Spring缓存抽象的服务类,如何以返回Optional的方式注释方法?
class MyServiceImpl implements MyService {
private static final String CACHE_NAME = "itemCache";
@Override
@Cacheable(CACHE_NAME)
public Optional<Item> findById(Long id) {
// access the repository to retrieve the item
}
@Override
@CachePut(cacheNames = CACHE_NAME, key = "#item.id")
public Item insertItem(Item item) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,ClassCastException抛出了a ,因为insertItem将Item实例放入缓存中,并findById期望Optional可能包含Item实例.
我正在尝试使用 spring 为我的应用程序构建缓存服务。缓存需要从数据库填充。
我的应用程序在三个节点上运行,并希望所有三个节点都与缓存同步。如果一个节点在缓存中获得更新的值,它应该通知其他节点。
我查看了Spring Cache 抽象,它没有谈论集群环境中的缓存。
有没有办法将缓存通知传播到其他节点?
我正在java中构建一个应用程序.我在循环中点击api超过15000次并获得响应(响应仅为静态)
例
**
username in for loop
GET api.someapi/username
processing
end loop
**
Run Code Online (Sandbox Code Playgroud)
完成所有通话需要几个小时.建议我以任何方式(任何缓存技术)来减少通话时间.
PS:
1)我从java rest客户端(Spring resttemplate)命中api
2)我打的是公开的,不是我开发的
3)将部署在heroku中
我使用 Spring Boot 版本:2.1.4.RELEASE
当我spring.cache.redis.time-to-live=20000在application.yml文件中设置时,我得到了一个例外。当我想在redis缓存中添加TTL时应该怎么做?如何在带有 Redis 的 Spring Cache 中使用缓存过期?
org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR wrong number of arguments for 'set' command
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:54)
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:52)
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:41)
at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44)
at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42)
at org.springframework.data.redis.connection.lettuce.LettuceConnection.convertLettuceAccessException(LettuceConnection.java:268)
at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.convertLettuceAccessException(LettuceStringCommands.java:799)
at org.springframework.data.redis.connection.lettuce.LettuceStringCommands.set(LettuceStringCommands.java:180)
at org.springframework.data.redis.connection.DefaultedRedisConnection.set(DefaultedRedisConnection.java:281)
at org.springframework.data.redis.cache.DefaultRedisCacheWriter.lambda$put$0(DefaultRedisCacheWriter.java:90)
at org.springframework.data.redis.cache.DefaultRedisCacheWriter.execute(DefaultRedisCacheWriter.java:242)
at org.springframework.data.redis.cache.DefaultRedisCacheWriter.put(DefaultRedisCacheWriter.java:87)
at org.springframework.data.redis.cache.RedisCache.put(RedisCache.java:159)
at org.springframework.cache.interceptor.AbstractCacheInvoker.doPut(AbstractCacheInvoker.java:87)
at org.springframework.cache.interceptor.CacheAspectSupport$CachePutRequest.apply(CacheAspectSupport.java:820)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:429)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:345)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at top.yunshu.shw.server.service.group.impl.GroupServiceImpl$$EnhancerBySpringCGLIB$$815b195d.findTeacherAllGroups(<generated>)
at top.yunshu.shw.server.controller.teacher.TeacherController.lambda$getTeacherCreateGroups$0(TeacherController.java:91)
at org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$4(WebAsyncManager.java:323)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266) …Run Code Online (Sandbox Code Playgroud) spring-cache ×10
java ×7
spring ×7
caching ×5
redis ×2
spring-boot ×2
asynchronous ×1
rest ×1
rest-client ×1
spring-data ×1