美文网首页
基于mysql的分布式锁

基于mysql的分布式锁

作者: 江江的大猪 | 来源:发表于2021-05-21 10:24 被阅读0次
  • 锁信息表sql

避免时区问题,expire_time使用bigint存储时间戳

CREATE TABLE IF NOT EXISTS `lock_info`
(
    `id`          bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
    `lock_key`    varchar(128)        NOT NULL COMMENT '加锁的key',
    `expire_time` bigint unsigned     NOT NULL COMMENT '过期时间',
    `create_ts`   datetime(3)         NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
    `update_ts`   datetime(3)         NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间',
    PRIMARY KEY (`id`),
    UNIQUE KEY `uk_lock_key` (`lock_key`)
) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT ='分布式锁信息表';

    <insert id="insert">
        INSERT INTO lock_info(lock_key, expire_time)
        VALUES(#{lockKey}, #{expireTime})
    </insert>

    <delete id="delete">
        delete from lock_info
        <where>
            and lock_key=#{lockKey}
            and expire_time=#{expireTime}
        </where>
        limit 1
    </delete>

    <update id="updateExpireTime">
        UPDATE lock_info
        <set>
            expire_time=#{newExpectTime},
        </set>
        <where>
            and lock_key=#{lockKey}
            and expire_time=#{oldExpectTime}
        </where>
    </update>

    <select id="select" resultType="cn.laifuzhi.template.model.PO.LockInfoPO">
        select id,
        lock_key as lockKey,
        expire_time as expireTime,
        create_ts as createTs,
        update_ts as updateTs
        from lock_info
        <where>
            and lock_key=#{lockKey}
        </where>
    </select>

@Slf4j
@Service
public class LockService {
    @Resource
    private LockInfoDao lockInfoDao;

    public Date tryLock(String lockKey, int expireSeconds) {
        Preconditions.checkArgument(StringUtils.isNotBlank(lockKey));
        try {
            Date now = new Date();
            Date newExpireTime = DateUtils.addSeconds(now, expireSeconds);
            LockInfoPO dbLockInfo = lockInfoDao.select(lockKey);
            if (dbLockInfo == null) {
                dbLockInfo = new LockInfoPO();
                dbLockInfo.setLockKey(lockKey);
                dbLockInfo.setExpireTime(newExpireTime);
                lockInfoDao.insert(dbLockInfo);
                return newExpireTime;
            }
            // 锁还未到过期时间,或者更新过期时间失败
            Date oldExpireTime = dbLockInfo.getExpireTime();
            if (now.before(oldExpireTime)
                    || lockInfoDao.updateExpireTime(lockKey, oldExpireTime, newExpireTime) <= 0) {
                return null;
            }
            log.info("tryLock key:{} expire:{}", lockKey, DateFormatUtils.format(newExpireTime, DATETIME_FORMAT));
            return newExpireTime;
        } catch (DuplicateKeyException e) {
            log.debug("tryLock duplicate key:{}", lockKey);
            return null;
        } catch (Exception e) {
            log.error("tryLock error key:{}", lockKey, e);
            return null;
        }
    }

    public void release(String lockKey, Date expectExpireTime) {
        Preconditions.checkArgument(StringUtils.isNotBlank(lockKey));
        try {
            boolean result = lockInfoDao.delete(lockKey, expectExpireTime) > 0;
            log.info("release key:{} expect:{} result:{}", lockKey, DateFormatUtils.format(expectExpireTime, DATETIME_FORMAT), result);
        } catch (Exception e) {
            log.error("release key error key:{} expect:{}", lockKey, DateFormatUtils.format(expectExpireTime, DATETIME_FORMAT), e);
        }
    }
}

相关文章

  • 基于MongoDB(Mongoose)的分布式锁实现

    当分布式部署的时候, 简单的本地锁是没办法满足需求的. 实现分布式锁的方法多样, 比如基于Mysql或Redis的...

  • 分布式锁实现

    基于数据库实现分布式锁基于缓存(redis,memcached)实现分布式锁基于Zookeeper实现分布式锁 s...

  • Redis实现分布式锁

    分布式下的分布式锁一般实现有三种: 基于数据库的乐观锁 基于redis的分布式锁 基于zookeeper的分布式锁...

  • 分布式锁的实现方式

    分布式锁通常有3种实现方式,即数据库乐观锁、基于redis的分布式锁和基于zookeeper的分布式锁。 一、基于...

  • 分布式锁之Redis实现(acquire)

    分布式锁一般有三种实现方式: 基于数据库的锁; 基于Redis的分布式锁; 基于ZooKeeper的分布式锁。 本...

  • 基于redis的分布式锁

    分布式锁实现方案 基于数据库实现分布式锁 基于缓存(redis,memcached,tair)实现分布式锁 基于Z...

  • 基于redis实现的分布式锁

    本文要点 基于redis实现分布式锁demo 基于redis实现分布式锁原理 基于redis实现分布式锁优缺点 正...

  • Redis实现分布式锁

    1. 分布式锁分类 数据库乐观锁 基于Redis的分布式锁 基于ZooKeeper的分布式锁 2. 组件依赖 po...

  • Redis分布式锁实现

    分布式锁实现方式 数据库乐观锁; 基于Redis的分布式锁; 基于ZooKeeper的分布式锁。 本篇将介绍第二种...

  • 通过redis实现分布式锁

    前言 分布式锁一般有三种实现方式: 数据库乐观锁; 基于Redis的分布式锁; 基于ZooKeeper的分布式锁。...

网友评论

      本文标题:基于mysql的分布式锁

      本文链接:https://www.haomeiwen.com/subject/iwpmjltx.html