오프라인 선점 잠금
오프라인 선점 잠금을 위한 LockManager 인터페이스와 관련 클래스
@Getter
public class LockId {
public LockId(String value) {
this.value = value;
}
private String value;
}
public interface LockManager {
LockId tryLock(String type, String id) throws LockException;
void checkLock(LockId lockId) throws LockException;
void releaseLock(LockId lockId) throws LockException;
void extendLockExpiration(LockId lockId, long inc) throws LockException;
}
LockManager.tryLock을 이용해 잠금 선점을 시도하고 잠금 된 LockId를 반환한다.
반환된 LockId는 잠금 해체를 할때 사용하므로 수정폼(view)에 보관해야 한다.
선점 잠금에 실패하면 LockException이 발생하는데 이때 다른 사용자가 데이터를 수정 중이니 나중에 다시 시도해 보라는 안내 화면을 보여주면 된다.
수정 폼 접근 예시
@RequestMapping("/some/edit/{id}")
public String editData(@PathVariable("id") Long id, ModelMap model) {
// 오프라인 선점 잠금 시도
LockId lockId = lockManager.tryLock("data", id);
// 기능 실행
Data data = someDao.select(id);
model.addAttribute("data", data);
// 잠금 해제에 사용할 LockId를 모델에 추가
model.addAttribute("lockId", lockId);
return "editData";
}
<!-- editData.jsp -->
<form action="/some/edit/${data.id}" nmethod="post">
...
<input type="hidden" name="lockId" value="${lockId.value}"/>
...
</form>