我最近在做一个项目,在仓库这个模块,我打算在第一次查询的时候,把所有的仓库数据全部存储起来,后面查询的时候就直接返回缓存就可以了。
在执行修改仓库操作的时候,顺便修改缓存。但是,我想这个时候如果出现了异常,springboot回滚了事务,但是缓存却被修改了。
所以,我想问有没有什么解决办法。我想的是,springboot有没有什么处理异常的方式
在方法上使用 @Cacheable 注解,注解里可以设置条件,一般是判断方法返回成功,满足这个条件才更新注解。
通常是查询方法上使用这个注解,查询成功的结果放入缓存。修改方法上使用 @CachePut 更新缓存,也可以和删除方法一样,使用 @CacheEvit 驱逐缓存。同样可以设置条件,方法执行成功才执行相应的缓存动作。
开启缓存功能需要在启动类上使用 @EnableCaching 注解。缓存条件使用SPEL表达式。
//清理某个分类下面的菜品缓存数据
String key = "dish_" + dishDto.getCategoryId() + "_1";
redisTemplate.delete(key);
回答:
在SpringBoot项目中实现仓库数据的缓存以提高查询效率,可以使用Spring Cache,具体步骤如下:
1.在pom.xml中添加spring-boot-starter-cache的依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
2.在启动类上添加@EnableCaching注解开启缓存:
@SpringBootApplication
@EnableCaching
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
3.在需要缓存的方法上添加注解@Cacheable并设置value和key属性:
@Service
public class MyService {
// 缓存结果,value为缓存的名称,key为缓存的key
@Cacheable(value = "myCache", key = "#id")
public MyObject getObjectById(long id) {
// 从数据库或其他数据源中查询数据
return getObjectFromDB(id);
}
}
4.如果需要在更新数据时清除缓存,可以在更新方法上添加注解@CacheEvict并设置value和key属性:
@Service
public class MyService {
// 更新数据,清除缓存,value为缓存的名称,key为缓存的key
@CacheEvict(value = "myCache", key = "#id")
@Transactional
public void updateObjectById(long id, MyObject newObj) {
// 更新数据
updateObjectToDB(id, newObj);
}
}
当发生异常导致事务回滚时,由于Spring Cache是基于注解实现的,只要在修改的方法上添加了@CacheEvict注解,即使发生异常导致事务回滚,缓存也会被正确地清除,不会产生不正确地修改缓存的情况。
另外,在SpringBoot中可以使用@ControllerAdvice和@ExceptionHandler注解来处理异常,具体步骤如下:
1.自定义一个异常处理类,并添加@ControllerAdvice注解:
@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public String handleException(Exception e) {
// 处理异常
return "error";
}
}
2.在异常处理方法上添加@ExceptionHandler注解,并传入要处理的异常类型:
@ControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(IOException.class)
@ResponseBody
public String handleIOException(IOException e) {
// 处理IOException
return "io_error";
}
}
这样,在代码中如果出现IOException异常,就会自动进入handleIOException方法进行处理,返回的结果可以自定义。
简单的方法,判断影响的行数是否大于0,如果大于0的话就操作缓存,比如
int row = configMapper.insertConfig(config);
if (row > 0)
{
redisCache.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
}
return row;