Kaynağa Gözat

修复内存锁的bug,并增加评卷过程的锁控制,避免出现重复领取已评任务的问题

luoshi 6 yıl önce
ebeveyn
işleme
5e15d88178

+ 8 - 4
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/lock/impl/MemoryLockProvider.java

@@ -26,8 +26,10 @@ public class MemoryLockProvider implements LockProvider {
     @Override
     public void waitLock(LockType type, String key) {
         AtomicBoolean lock = getLock(type, key);
-        while (!lock.get()) {
-            lock.compareAndSet(false, true);
+        while (true) {
+            if (lock.compareAndSet(false, true)) {
+                return;
+            }
         }
     }
 
@@ -46,8 +48,10 @@ public class MemoryLockProvider implements LockProvider {
     @Override
     public void unlock(LockType type, String key) {
         AtomicBoolean lock = getLock(type, key);
-        while (lock.get()) {
-            lock.compareAndSet(true, false);
+        while (true) {
+            if (lock.compareAndSet(true, false)) {
+                return;
+            }
         }
     }
 

+ 33 - 36
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/MarkLockService.java

@@ -35,10 +35,7 @@ public class MarkLockService {
      * @param group
      */
     public void lockGroup(Integer examId, String subjectCode, Integer groupNumber) {
-        AtomicBoolean lock = getLock(groupMap, getKey(examId, subjectCode, groupNumber));
-        while (!lock.get()) {
-            lock.compareAndSet(false, true);
-        }
+        lock(getLock(groupMap, getKey(examId, subjectCode, groupNumber)));
     }
 
     /**
@@ -47,10 +44,7 @@ public class MarkLockService {
      * @param group
      */
     public void unlockGroup(Integer examId, String subjectCode, Integer groupNumber) {
-        AtomicBoolean lock = getLock(groupMap, getKey(examId, subjectCode, groupNumber));
-        while (lock != null && lock.get()) {
-            lock.compareAndSet(true, false);
-        }
+        unlock(getLock(groupMap, getKey(examId, subjectCode, groupNumber)));
     }
 
     /**
@@ -59,10 +53,7 @@ public class MarkLockService {
      * @param group
      */
     public void waitUnlockGroup(Integer examId, String subjectCode, Integer groupNumber) {
-        AtomicBoolean lock = getLock(groupMap, getKey(examId, subjectCode, groupNumber));
-        while (lock.get()) {
-            ;
-        }
+        waitUnlock(getLock(groupMap, getKey(examId, subjectCode, groupNumber)));
     }
 
     /**
@@ -71,10 +62,7 @@ public class MarkLockService {
      * @param studentId
      */
     public void lockStudent(Integer studentId) {
-        AtomicBoolean lock = getLock(studentMap, studentId);
-        while (!lock.get()) {
-            lock.compareAndSet(false, true);
-        }
+        lock(getLock(studentMap, studentId));
     }
 
     /**
@@ -83,10 +71,7 @@ public class MarkLockService {
      * @param studentId
      */
     public void unlockStudent(Integer studentId) {
-        AtomicBoolean lock = getLock(studentMap, studentId);
-        while (lock.get()) {
-            lock.compareAndSet(true, false);
-        }
+        unlock(getLock(studentMap, studentId));
     }
 
     /**
@@ -95,10 +80,7 @@ public class MarkLockService {
      * @param studentId
      */
     public void waitUnlockStudent(Integer studentId) {
-        AtomicBoolean lock = getLock(studentMap, studentId);
-        while (lock.get()) {
-            ;
-        }
+        waitUnlock(getLock(studentMap, studentId));
     }
 
     /**
@@ -107,10 +89,7 @@ public class MarkLockService {
      * @param markerId
      */
     public void lockMarker(Integer markerId) {
-        AtomicBoolean lock = getLock(markerMap, markerId);
-        while (!lock.get()) {
-            lock.compareAndSet(false, true);
-        }
+        lock(getLock(markerMap, markerId));
     }
 
     /**
@@ -119,10 +98,7 @@ public class MarkLockService {
      * @param markerId
      */
     public void unlockMarker(Integer markerId) {
-        AtomicBoolean lock = getLock(markerMap, markerId);
-        while (lock.get()) {
-            lock.compareAndSet(true, false);
-        }
+        unlock(getLock(markerMap, markerId));
     }
 
     /**
@@ -131,10 +107,7 @@ public class MarkLockService {
      * @param studentId
      */
     public void waitUnlockMarker(Integer markerId) {
-        AtomicBoolean lock = getLock(markerMap, markerId);
-        while (lock.get()) {
-            ;
-        }
+        waitUnlock(getLock(markerMap, markerId));
     }
 
     public void clear() {
@@ -179,4 +152,28 @@ public class MarkLockService {
         return examId + "_" + subjectCode + "_" + groupNumber;
     }
 
+    private void lock(AtomicBoolean lock) {
+        while (true) {
+            if (lock.compareAndSet(false, true)) {
+                return;
+            }
+        }
+    }
+
+    private void unlock(AtomicBoolean lock) {
+        while (true) {
+            if (lock.compareAndSet(true, false)) {
+                return;
+            }
+        }
+    }
+
+    private void waitUnlock(AtomicBoolean lock) {
+        while (true) {
+            if (!lock.get()) {
+                return;
+            }
+        }
+    }
+
 }

+ 13 - 9
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/MarkServiceImpl.java

@@ -227,6 +227,17 @@ public class MarkServiceImpl implements MarkService {
         return CurrentTaskUtil.exists(marker, getApplyTaskId(library));
     }
 
+    /**
+     * 释放某个评卷员已领取的任务
+     * 
+     * @param library
+     * @param marker
+     */
+    @Override
+    public void releaseLibrary(MarkLibrary library, Marker marker) {
+        CurrentTaskUtil.remove(marker, getApplyTaskId(library));
+    }
+
     /**
      * 释放某个评卷员的所有锁定任务
      * 
@@ -310,12 +321,10 @@ public class MarkServiceImpl implements MarkService {
         lockService.waitUnlockGroup(group.getExamId(), group.getSubjectCode(), group.getNumber());
         // 等待考生释放锁定
         lockService.waitUnlockStudent(library.getStudentId());
-        // 本人是否已领取该任务
-        boolean applied = hasApplied(library, marker);
 
         try {
             // 非本人领取的待评任务
-            if (library.getStatus() == LibraryStatus.WAITING && !applied) {
+            if (library.getStatus() == LibraryStatus.WAITING && !hasApplied(library, marker)) {
                 return false;
             }
             // 非本人的回评任务
@@ -384,12 +393,7 @@ public class MarkServiceImpl implements MarkService {
             updateLibraryCount(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
             return true;
         } catch (Exception e) {
-            throw e;
-        } finally {
-            // 只有确定本人已领取该任务时,才进行释放操作
-            if (applied) {
-                CurrentTaskUtil.remove(marker, getApplyTaskId(library));
-            }
+            throw new RuntimeException("submit library error", e);
         }
     }
 

+ 8 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/MarkService.java

@@ -15,6 +15,14 @@ import cn.com.qmth.stmms.common.enums.ScorePolicy;
 
 public interface MarkService {
 
+    /**
+     * 释放某个评卷员已领取的任务
+     * 
+     * @param library
+     * @param marker
+     */
+    void releaseLibrary(MarkLibrary library, Marker marker);
+
     /**
      * /** 释放某个大题的锁定任务
      * 

+ 5 - 9
stmms-web/src/main/java/cn/com/qmth/stmms/mark/MarkController.java

@@ -199,15 +199,8 @@ public class MarkController extends BaseController {
     @ResponseBody
     public Task getTask(HttpServletRequest request) {
         Marker marker = RequestUtils.getWebUser(request).getMarker();
-        Task task = null;
-        try {
-            lockService.lockMarker(marker.getId());
-            task = getTask(marker);
-        } catch (Exception e) {
-            log.error("get task error", e);
-        } finally {
-            lockService.unlockMarker(marker.getId());
-        }
+        lockService.waitUnlockMarker(marker.getId());
+        Task task = getTask(marker);
         if (task == null) {
             task = new Task();
             task.setExist(false);
@@ -271,6 +264,9 @@ public class MarkController extends BaseController {
             library.setTags(StringUtils.trimToNull(task.getTags()));
             success = markService.submitLibrary(library, marker, task.getTrackList(library),
                     task.getSpecialTagList(library));
+            if (success) {
+                markService.releaseLibrary(library, marker);
+            }
         } catch (Exception e) {
             log.error("save task error", e);
         } finally {