redisson
未读前言
说起 Redisson,比较耳熟能详的就是这个看门狗(Watchdog)机制。
本文就一起看看加锁成功之后的看门狗(Watchdog)是如何实现的?
加锁成功
在前一篇文章中介绍了可重入锁加锁的逻辑,其中 RedissonLock#tryAcquireAsync 方法是进行异步加锁的逻辑。
回顾一下这个方法的入参:
waitTime:-1;
leaseTime:-1,加锁时未指定锁时间,则为 -1,如果指定,则是指定的时间;
unit:null;
threadId:当前线程 id。
其中的 tryLockInnerAsync 在之前已经介绍过了。
当加锁成功时,会返回 null,加锁失败,会返回当前锁的剩余时间。
所以这块会进入到红框标记的部分。
leaseTime 为加锁时间,默认不指定,所以会进入到 scheduleExpirationRenewal 方法,也就是今天的主题:看门狗。
至此可以得出一个结论:
Redisson 看门狗(Watchdog)在指定加锁时间时,是不会对锁时间自动续租的。
看门狗
看门狗的一部分重点逻辑就在 renewExpiration 方 ...
redisson
未读前言
相信小伙伴都是使用分布式服务,那一定绕不开分布式服务中数据并发更新问题!
单系统很容易想到 Java 的各种锁,像 synchronize、ReentrantLock 等等等,那分布式系统如何处理?
当然是使用分布式锁。
如果小伙伴不知道什么是分布式锁,那推荐看看石杉老师的突击课或者在网上搜一搜相关资料。
当使用 Redis 作为分布式锁时,当前使用较多的框架就是 Redisson。
当然 Redisson 也不仅仅只能当做锁来使用,也有很多其他的功能,小伙伴们可以看一看官方文档,自己多动手实践一下。
下面就开始记录 Redisson 的相关笔记!错误之处,欢迎指正。🙏🏻
环境配置
本地环境搭建的伪集群:
redisson 3.15.6
不同版本可能会有所不同,但是核心思想不会发生太大变化,如果变化很大,希望可以留言。
12345<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> &l ...
前言
三篇文章分别通过实际操作,介绍了主键、非主键唯一索引、普通索引、普通字段四个方面介绍了加锁的范围。
本篇文章再做一个总结。
data_locks
1select * from performance_schema.data_locks;
LOCK_MODE
LOCK_DATA
锁范围
X,REC_NOT_GAP
15
15 那条数据的行锁
X,GAP
15
15 那条数据之前的间隙,不包含 15
X
15
15 那条数据的间隙,包含 15
LOCK_MODE = X 是前开后闭区间;
X,GAP 是前开后开区间(间隙锁);
X,REC_NOT_GAP 行锁。
这个单独介绍,是希望我理解的没有错误,如果大佬看到了,错误之处一定要帮忙指正出来。
主键索引
加锁时,会先给表添加意向锁,IX 或 IS;
加锁是如果是多个范围,是分开加了多个锁,每个范围都有锁;(这个可以实践下 id < 20 的情况)
主键等值查询,数据存在时,会对该主键索引的值加行锁 X,REC_NOT_GAP;
主键等值查询,数据不存在时,会对查询条件主键值所在的间隙添加间隙锁 ...
前言
近日小伙伴提建议希望 Toolkit 支持 lombok。
个人认为 GsonFormat 不香么?
我没使用 GsonFormat,所以为什么不能用的,我也没法给评价。
不过,既然是小伙伴的需求,那还是得加的!
功能介绍
下载地址
在官方插件库搜索 Toolkit
github:https://github.com/liuzhihang/toolkit/releases
mysql
未读前言
前面已经介绍了主键索引的加锁范围和非主键唯一索引的加锁范围。
主键索引:
加锁时,会先给表添加意向锁,IX 或 IS;
加锁是如果是多个范围,是分开加了多个锁,每个范围都有锁;(这个可以实践下 id < 20 的情况)
主键等值查询,数据存在时,会对该主键索引的值加行锁 X,REC_NOT_GAP;
主键等值查询,数据不存在时,会对查询条件主键值所在的间隙添加间隙锁 X,GAP;
主键等值查询,范围查询时情况则比较复杂:
8.0.17 版本是前开后闭,而 8.0.18 版本及以后,修改为了前开后开区间;
临界 <= 查询时,8.0.17 会锁住下一个 next-key 的前开后闭区间,而 8.0.18 及以后版本,修复了这个 bug。
非主键唯一索引:
非主键唯一索引等值查询,数据存在,for update 是会在主键加锁的,而 for share 只有在走覆盖索引的情况下,会仅在自己索引上加锁;
非主键索引等值查询,数据不存在,无论是否索引覆盖,相当于一个范围查询,仅仅会在非主键索引上加锁,加的还是间隙锁,前开后开区间;
在非主键唯一索引范围查询时,不是 ...
前言
在上一篇文章《MySQL next-key lock 加锁范围是什么?》中已经介绍了主键索引的加锁范围,现在来回顾一下:
加锁时,会先给表添加意向锁,IX 或 IS;
加锁是如果是多个范围,是分开加了多个锁,每个范围都有锁;(这个可以实践下 id < 20 的情况)
主键等值查询,数据存在时,会对该主键索引的值加行锁 X,REC_NOT_GAP;
主键等值查询,数据不存在时,会对查询条件主键值所在的间隙添加间隙锁 X,GAP;
主键等值查询,范围查询时情况则比较复杂:
8.0.17 版本是前开后闭,而 8.0.18 版本及以后,修改为了前开后开区间;
临界 <= 查询时,8.0.17 会锁住下一个 next-key 的前开后闭区间,而 8.0.18 及以后版本,修复了这个 bug。
这篇文章会对非主键唯一索引进行操作实践。
数据库表数据
123456789CREATE TABLE `t` ( `id` int NOT NULL COMMENT '主键', `a` int DEFAULT NULL COMMENT '唯一索引& ...
docker
未读前言
作为开发,在本机捣鼓一下 Docker 还是很有必要的,本篇文章介绍如何使用 Docker 安装 MySQL,并在终端(iTerm2)使用命令连接 MySQL。
安装 MySQL
核心命令如下:
1234567# 用 8.0.17 版本举例docker pull mysql:8.0.17# 运行 mysqldocker run -itd --name mysql8.0.17 -p 23306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:8.0.17docker ps
登录 MySQL
1234# 进入容器docker exec -it mysql8.0.17 bash# 登录 mysqlmysql -u root -p
前言
某天,突然被问到 MySQL 的 next-key lock,我瞬间的反应就是:
这都是啥啥啥???
这一个截图我啥也看不出来呀?
仔细一看,好像似曾相识,这不是《MySQL 45 讲》里面的内容么?
什么是 next-key lock
A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record.
官网的解释大概意思就是:next-key 锁是索引记录上的记录锁和索引记录之前的间隙上的间隙锁的组合。
先给自己来一串小问号???
在主键、唯一索引、普通索引以及普通字段上加锁,是锁住了哪些索引?
不同的查询条件,分别锁住了哪些范围的数据?
for share 和 for update 等值查询和范围查询的锁范围?
当查询的等值不存在时,锁范围是什么?
当查询条件分别是主键、唯一索引、普通索引时有什么区别?
既然啥都不懂,那只好从头开始操作实践一把了!
先看看看 《MySQL 45 讲》中丁奇老 ...
前言
记录一下自己用的 Mac 软件,如果小伙伴需要,可以下载体验一下。
在 Github 上有一个地址:
https://github.com/jaywcjlove/awesome-mac/blob/master/README-zh.md
这里仅介绍我所使用过,并一直在使用,而且觉得很不错的软件推荐给小伙伴。
开发工具
作为开发,必须得把吃饭的家伙放在第一位!
IntelliJ IDEA
相关地址:IntelliJ IDEA
IDEA,就是吃饭的家伙,没啥可介绍的。
这里额外推荐我的 IDEA 插件:
Toolkit:支持MyBatis、Json、XML、Base64等操作的工具包。
Doc View:一个IntelliJ IDEA插件,可以通过注释直接生成Markdown文档。
DataGrip
相关地址:DataGrip
虽然 IDEA 中内置了数据库工具,但是相比而言,更喜欢用独立的客户端 DataGrip,尤其是编写 SQL 的时候,各种快捷键、实时模版、代码提醒都非常方便。
Navicat Premium
相关地址:Navicat Premium
DataGrip ...
前言
前段时间有小伙伴在群里聊天,说到 Toolkit 下载量到 4.9k 了。就突然想起来,很久没有更新这个插件。
PS:我是用它申请了 License,一般时候使用 Json 格式化功能。
趁着周末,更新了下版本,下面介绍直接介绍更新后的版本。
功能介绍
UI 界面
这次修改最大的就是 UI 界面,基本参考 Doc View 的 UI,全面进行改造,同时对代码也进行的一定程度上的重构。
同时增加快捷键 Control + Shift + T 直接唤起操作面板的功能。
UI 界面调整,以标签页的形式直接展示功能,方便使用。
Json Format
保留原有功能:
代码格式化;
压缩为一行;
移除文本中的转移符(\);
快捷生成实体类字段。
新增功能:
快捷复制;
原生查找。
动图演示:
快捷键打开
Json 格式化
压缩 Json 字符串为一行
查找字段
因为直接使用的原生 Editor 当做面板,所以是支持 ⌘ + F 直接局内搜索的。
生成字段
到这里关于 Json 工具的介绍基本就结束了,这也是我在开发过成功经常用到的几个功能。当然 ...
前言
建造者模式是一种创建型设计模式,使你能够分步骤创建复杂对象。该模式允许你使用相同的创建代码生成不同类型和形式的对象。
一个 Builder 类会一步一步构造最终对象。这个 Builder 类是独立于其他对象的。
使用场景
在阅读源码过程中经常看到建造者模式,主要是为了简化复杂对象的创建。
具体那些房子啥的举例子就不扯了,以实际工作中的应用为主。
@Builder 注解
如果小伙伴使用 lombok 这个框架的话,那一定对 @Builder 这个注解不会陌生。
123456789101112131415161718192021@Data@Builderpublic class UserRespVo { /** * 用户名字 */ private String userName; /** * 用户 id */ private String userId; public static void main(String[] args) { UserRespVo respVo = UserR ...
前言
策略模式是一种行为设计模式,它能让你定义一系列算法,并将每种算法分别放入独立的类中,以使算法的对象能够相互替换。
使用场景
策略模式在工作中使用的相对是比较多的,像支付场景,计费场景,优惠场景,活动奖励、用户等级等等。
当然也有很多直白的说法,就是替换一大堆的 if else。
1234567if (x == aaa) { // 200 行代码} else if (x == bbb) { // 200 行代码} else if (x == ccc) { // 200 行代码}
按照上面的 if else 逻辑,其中 aaa、bbb、ccc 就是不同的策略。而使用策略模式的目的,就是当又增加了 ddd、eee 等等的时候,更方便的扩展。
这里以工作中遇到的场景举例:
这里选择使用计费场景中的计费策略举例:
在计费场景中,需要每日给用户发放利息,同时用户分为普通用户、持卡用户,他们有分别的利率以及计息方式。
很明显,在计费时要使用策略模式,按照以下模式进行开发。
使用方式
定义计算接口
1234pub ...