Browse Source

feat: 支持ehcache缓存,缓存一致性

haha 4 years ago
parent
commit
b9452fd227

+ 0 - 1
seec-oj-server/src/main/java/cn/seecoder/ojserver/controller/ProblemController.java

@@ -34,7 +34,6 @@ public class ProblemController {
 
     @GetMapping("/{problemId:\\d+}")
     public Response getProblemById(@PathVariable int problemId){
-        System.out.println(this.problemService.getProblemById(problemId));
         return Response.buildSuccess(this.problemService.getProblemById(problemId));
     }
 

+ 3 - 2
seec-oj-server/src/main/java/cn/seecoder/ojserver/manager/QuestionManager.java

@@ -7,6 +7,7 @@ import cn.seecoder.ojserver.dao.TestCaseDAO;
 import cn.seecoder.ojserver.exception.ThirdPartyServiceException;
 import cn.seecoder.ojserver.model.vo.CompleteQuestionVO;
 import cn.seecoder.ojserver.utils.thirdparty.QuestionThirdPartyService;
+import org.springframework.cache.annotation.CacheConfig;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
@@ -27,13 +28,13 @@ public class QuestionManager {
     }
 
 
-    @Cacheable(value = "problem")
+    @Cacheable(value = "problem",key = "#id")
     public Optional<Problem> getProblemById(Integer id){
         System.out.println("getProblemById:"+id);
         return problemDAO.findById(id);
     }
 
-    @Cacheable(value = "testCaseByProblemId")
+    @Cacheable(value = "problemTestCase" ,key = "#problemId")
     public List<TestCase> getTestCaseByProblemId(Integer problemId){
         System.out.println("getTestCaseByProblemId:"+problemId);
         return testCaseDAO.findByProblem_Id(problemId);

+ 7 - 0
seec-oj-server/src/main/java/cn/seecoder/ojserver/service/impl/ProblemServiceImpl.java

@@ -10,6 +10,9 @@ import cn.seecoder.ojserver.model.dto.ProblemDTO;
 import cn.seecoder.ojserver.model.vo.ProblemVO;
 import cn.seecoder.ojserver.model.vo.TestCaseVO;
 import cn.seecoder.ojserver.service.ProblemService;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
 
 import java.util.Date;
@@ -38,6 +41,7 @@ public class ProblemServiceImpl implements ProblemService {
     }
 
     @Override
+    @CacheEvict(value = {"problem","problemTestCase"}, key = "#problemId")
     public int delete(int problemId) {
         this.problemDAO.deleteById(problemId);
         return problemId;
@@ -71,6 +75,7 @@ public class ProblemServiceImpl implements ProblemService {
     }
 
     @Override
+    @CacheEvict(value = "problemTestCase",key = "#testCaseVO.problemId")
     public TestCaseVO addTestCase(TestCaseVO testCaseVO) {
         TestCase testCase = TestCaseMapper.INSTANCE.toPO(testCaseVO);
         Problem problem = new Problem();
@@ -81,6 +86,7 @@ public class ProblemServiceImpl implements ProblemService {
     }
 
     @Override
+    @CacheEvict(value = "problemTestCase",allEntries = true)
     public List<TestCaseVO> addTestCaseList(List<TestCaseVO> testCaseVOList) {
         List<TestCase> testCaseList = TestCaseMapper.INSTANCE.toPOList(testCaseVOList);
         for(int i=0;i<testCaseList.size();i++){
@@ -94,6 +100,7 @@ public class ProblemServiceImpl implements ProblemService {
 
 
     @Override
+    @CacheEvict(value = "problemTestCase", allEntries = true)
     public String deleteTestCase(Integer testcaseId) {
         this.testCaseDAO.deleteById(testcaseId);
         return "删除测试用例成功";

+ 4 - 0
seec-oj-server/src/main/resources/application-test.yml

@@ -6,6 +6,10 @@ spring:
     username: root
     password: root
     driver-class-name: com.mysql.cj.jdbc.Driver
+    cache:
+      type: ehcache
+      ehcache:
+        config: ehcache.xml
     # 连接池
     hikari:
       #连接池名

+ 60 - 0
seec-oj-server/src/main/resources/ehcache.xml

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ehcache updateCheck="false" name="defaultCache">
+
+    <!--
+       diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置,可以自定义目录,确保用户有权限即可。参数解释如下:
+       user.home – 用户主目录
+       user.dir  – 用户当前工作目录
+       java.io.tmpdir – 默认临时文件路径
+     -->
+
+    <!-- maxElementsInMemory:内存中最大缓存对象数,根据服务器资源配置 -->
+    <!-- eternal: 默认为false,设置true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性, -->
+    <!-- maxElementsOnDisk:硬盘中最大缓存对象数,若是0表示无穷大 -->
+    <!-- overflowToDisk:true表示当内存缓存的对象数目达到了maxElementsInMemory界限后,会把溢出的对象写到硬盘缓存中。
+    注意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行。-->
+    <!-- diskSpoolBufferSizeMB:磁盘缓存区大小,默认为30MB。每个Cache都应该有自己的一个缓存区。-->
+    <!-- diskPersistent:是否缓存虚拟机重启期数据  -->
+    <!-- diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认为120秒 -->
+
+    <!-- timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,单位(秒)。自对象最近一次被访问后,
+    空闲时间超过了timeToIdleSeconds属性值,这个对象就会过期,如果该属性值为0,则对象无限期地处于空闲状态
+    EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。
+    -->
+
+    <!-- timeToLiveSeconds:设定允许对象存在于缓存中的最长时间,单位(秒)。自对象被存放到缓存中后,
+    在缓存中的时间超过了timeToLiveSeconds属性值,这个对象就会过期,如果该属性值为0,则对象无限期地存在于缓存中。
+    EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义 -->
+
+    <!-- memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。
+    可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。-->
+
+    <!-- 默认缓存 -->
+    <defaultCache
+            maxElementsInMemory="10000"
+            eternal="false"
+            overflowToDisk="false"
+            diskSpoolBufferSizeMB="50"
+            timeToIdleSeconds="300"
+            timeToLiveSeconds="600"
+            maxElementsOnDisk="10000000"
+            diskExpiryThreadIntervalSeconds="120"
+            memoryStoreEvictionPolicy="LRU">
+
+    </defaultCache>
+
+    <cache name="problem"
+           maxElementsInMemory="100"
+           eternal="false"
+           timeToIdleSeconds="30"
+           timeToLiveSeconds="300"
+           memoryStoreEvictionPolicy="LRU"/>
+
+    <cache name="problemTestCase"
+           maxElementsInMemory="1000"
+           eternal="false"
+           timeToIdleSeconds="30"
+           timeToLiveSeconds="300"
+           memoryStoreEvictionPolicy="LRU"/>
+
+</ehcache>