怎么在MySQL数据库中实现一个分布式锁
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章将为大家详细讲解有关怎么在MySQL数据库中实现一个分布式锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。建表CREATE TABLE `gl
千家信息网最后更新 2026年11月01日怎么在MySQL数据库中实现一个分布式锁
这篇文章将为大家详细讲解有关怎么在MySQL数据库中实现一个分布式锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
建表
CREATE TABLE `globallocktable` ( `id` int(11) NOT NULL AUTO_INCREMENT, `lockKey` varchar(60) NOT NULL COMMENT '锁名称', `createTime` datetime NOT NULL COMMENT '创建时间', PRIMARY KEY (`id`), UNIQUE KEY `lockKey` (`lockKey`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='全局锁';
让别人使用的组件
@Componentpublic class GlobalLockComponent { @Resource GlobalLockTableDAO globalLockDAO; /** * 尝试获得锁,成功为true,失败为false */ public boolean tryLock(String key) { return GlobalLockUtil.tryLock(this.globalLockDAO, key); } /** * 如果已经有其他程序占用该锁,并且超过timeoutMs(毫秒)时间,就强制清除这个锁占用 * 即根据key先删除记录,再添加记录 */ public boolean tryLockWithClear(String key, Long timeoutMs) { return GlobalLockUtil.tryLockWithClear(this.globalLockDAO, key, timeoutMs); } /** * 释放锁,根据key删除记录 */ public void releasLock(String key) { GlobalLockUtil.releasLock(this.globalLockDAO, key); }}锁对象定义如下
public class GlobalLockTable { private Integer id; private String lockKey; private Date createTime; // 省略get和set方法}GlobalLockTableDAO定义如下public interface GlobalLockTableDAO { int deleteByPrimaryKey(Integer id); int deleteByLockKey(String lockKey); GlobalLockTable selectByLockKey(String key); int insertSelectiveWithTest(GlobalLockTable record);}具体加锁和解锁逻辑
public class GlobalLockUtil { private static Logger logger = LoggerFactory.getLogger(GlobalLockUtil.class); private static GlobalLockTable tryLockInternal(GlobalLockTableDAO lockDAO, String key) { GlobalLockTable insert = new GlobalLockTable(); insert.setCreateTime(new Date()); insert.setLockKey(key); // 注意的地方1 int count = lockDAO.insertSelectiveWithTest(insert); if (count == 0) { GlobalLockTable ready = lockDAO.selectByLockKey(key); logger.warn("can not lock the key: {}, {}, {}", insert.getLockKey(), ready.getCreateTime(), ready.getId()); return ready; } logger.info("yes got the lock by key: {}", insert.getId(), insert.getLockKey()); return null; } /** 超时清除锁占用,并重新加锁 **/ public static boolean tryLockWithClear(GlobalLockTableDAO lockDAO, String key, Long timeoutMs) { GlobalLockTable lock = tryLockInternal(lockDAO, key); if (lock == null) return true; if (System.currentTimeMillis() - lock.getCreateTime().getTime() <= timeoutMs) { logger.warn("sorry, can not get the key. : {}, {}, {}", key, lock.getId(), lock.getCreateTime()); return false; } logger.warn("the key already timeout wthin : {}, {}, will clear", key, timeoutMs); // 注意的地方2 int count = lockDAO.deleteByPrimaryKey(lock.getId()); if (count == 0) { logger.warn("sorry, the key already preemptived by others: {}, {}", lock.getId(), lock.getLockKey()); return false; } lock = tryLockInternal(lockDAO, key); return lock != null ? false : true; } /** 加锁 **/ public static boolean tryLock(GlobalLockTableDAO lockDAO, String key) { return tryLockInternal(lockDAO, key) == null ? true : false; } /** 解锁 **/ public static void releasLock(GlobalLockTableDAO lockDAO, String key) { lockDAO.deleteByLockKey(key); }}这个工具类有2个特别有意思的地方,先看注意的地方2(上面代码中标识了)
1.为了避免锁长时间不释放,用Redis实现的话可以设置锁超时时间,超时自动释放(后面会写用Redis实现分布式锁)用MySQL实现的话可以先删除后添加。可以看到删除的时候使用id删的,不是用name删的。为啥呢?先自己想一下
因为如果是通过name删的话,有可能别人删了这个锁后,又通过name加了锁,还没到超时时间,结果你却根据name删除了。通过id删的话,当返回的id=0时,说明别人已经重新加锁了,你需要重新获取。
2.GlobalLockTable 对象dao层的其他方法都见名知意,来看一个这个方法。即代码中的注意点1
可以看到每次尝试加锁的时候,并不是先select,而是直接insertSelectiveWithTest,这样就少了一个查询时间,提高了效率
insertSelectiveWithTest的作用是当lockKey存在时不进行插入操作,返回0。当lockKey不存在时进行插入操作,返回1
insert into `globallocktable` (`id`, `lockKey`, `createTime` ) select #{id,jdbcType=INTEGER}, #{lockKey,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP} from dual where not exists (select 1 from globallocktable where lockKey = #{lockKey,jdbcType=VARCHAR})
使用
当我们想使用时,就只写业务逻辑就行了,非常方便
if (!globalLockComponent.tryLock(name)) { // 没有获取到锁返回 return;}try { // 这里写业务逻辑} catch (Exception e) {} finally { globalLockComponent.releasLock(name)关于怎么在MySQL数据库中实现一个分布式锁就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
时间
地方
分布式
方法
逻辑
数据
数据库
中实
业务
代码
内容
对象
文章
时候
更多
知识
篇文章
尝试
不错
成功
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
上海挚品互联网科技有限公司
什么是科技互联网
互联网是不是新科技
互联网科技公司发展
互联网科技集团
天津摩尔互联网科技
撒么互联网科技公司
互联网科技公司名称
左右互联网络科技
上海电发互联网科技有限公司
互联网教育科技公司vipkid
字节跳动和互联网科技
苏州铭阳互联网科技有限公司
世界互联网领先科技成果获奖
中和天地互联网科技有限公司
华中科技大学互联网的牛人
张召忠谈中国互联网科技
国产互联网科技公司
科技互联网经济论坛
数字互联网科技有限公司
狮子座互联网科技有限公司
互联网金融科技委员会
中国最先进互联网科技公司
昭通云南众福互联网科技有限公司
互联网科技产业特征
晋城互联网科技
区块链结合互联网科技
张召忠谈中国互联网科技
互联网科技数字货币
同城互联网络科技