分布式锁

占位ing

通过zookeeper、consul等分布式协调服务实现

通过redis的原子操作实现

zookeeper

分布式排他锁

分布式读写锁:

读锁

写锁

 可参阅:https://www.cnblogs.com/z-sm/p/5691752.html

redis

分布式排他锁:借助redis的setnx原子操作。代码:

public class CourseExpEditDistributedLockUtil {
    /** 获取锁(可重入),在开始编辑课程或实验前调用。 */
    public static boolean lock(String entityId, LockedEntityTypeEnum entityType, String curUserId) {
        String redisKey = generateDistributedLockKey(entityId, entityType);
        String redisValue = generateDistributedLockValue(curUserId);

        {// 判断是否是重入操作,若是则直接成功
            String tmpVal = JedisPoolClientUtil.get(redisKey);
            if (null != tmpVal && tmpVal.equals(redisValue)) {
                return true;
            }
        }

        // 通过Redis setnx原子操作设置分布式锁。为防止获得锁后没释放,设置锁的最长持有时间
        String res = JedisPoolClientUtil.set(redisKey, redisValue, "nx", "ex", (long) (1 * 3600));// 设置值以获取分布式锁,并设置持有该锁的最长时间
        return null != res;
        // ApiCustomException.assertTrue(ApiErrorCode.FORBIDDEN, null != res,
        // "目标课程或实验正在被其他人编辑,请稍候");
    }

    /** 释放锁,已持有锁方可释放。在课程或实验编辑完后调用。 */
    public static boolean unLock(String entityId, LockedEntityTypeEnum entityType, String curUserId) {
        String redisKey = generateDistributedLockKey(entityId, entityType);
        String redisValueExcepted = generateDistributedLockValue(curUserId);

        String redisValueReal = JedisPoolClientUtil.get(redisKey);
        if (null != redisValueReal && redisValueReal.equals(redisValueExcepted)) {
            JedisPoolClientUtil.del(redisKey);
            return true;
        } else {
            return false;
        }
        // ApiCustomException.assertTrue(ApiErrorCode.NOT_EXIST_DATA, null !=
        // redisValueReal &&
        // redisValueReal.equals(redisValueExcepted),
        // "当前用户未持有目标课程或实验的编辑权");
    }

    /** 锁的key为目标Entity的信息 */
    private static String generateDistributedLockKey(String entityId, LockedEntityTypeEnum type) {
        return String.format("DistributedLock_%s_%s", type, entityId);
    }

    /** 锁的value */
    private static String generateDistributedLockValue(String curUserId) {
        return curUserId;
    }

    public static enum LockedEntityTypeEnum {
        COURSE, EXPERIMENT, CATALOG, COURSE_TRANSLATION, EXPERIMENT_TRANSLATION, CATALOG_TRANSLATION;
    }
}
View Code

...

原文地址:https://www.cnblogs.com/z-sm/p/10053636.html