使用Redis分布式锁

常见锁类执行逻辑:

1、写+写 阻塞排队

2、写+读 等待写结束

3、读+写(先读再写) 读完才能写!! 有读锁写也需要等待

4、多个读:相当于无锁,并发读会同时上锁成功,会记录所有的读

5、fair lock公平锁 并发执行之后有先后顺序,不是抢占,因此第一个执行结束将锁交给下一个人、

6、读写锁 写锁控制读锁,当有进程中在写的时候不能读取,只有当写入结束之后才可以读取 写锁自身也会等待

1、分布式锁与本地锁的区别

image-20220411163401780

2、本地锁

本地锁使用过程中,可以防止在一个微服务内部由于并发问题产生的读写数据不一致问题。

2.1 Synchronized关键字加锁

1、同步方法

1
2
3
4
5
6
7
8
9
10
11
12
//加锁方式1
public synchronized void method()
{
//TODO
}
//加锁方式2(同步方法中使用同步代码块)
public void method()
{
synchronized(this) {
// TODO
}
}

1.1、同步实例方法

阅读全文 »

行内与独行

  1. 行内公式:将公式插入到本行内,符号:$公式内容$,如:$xyz$

  2. 独行公式:将公式插入到新的一行内,并且居中,符号:

    1
    $$公式内容$$

    ,如:

    xyzxyz

上标、下标与组合

  1. 上标符号,符号:^,如:$x^4$
  2. 下标符号,符号:_,如:$x_1$
  3. 组合符号,符号:{},如:${16}{8}O{2+}{2}$

汉字、字体与格式

  1. 汉字形式,符号:\mbox{},如:$V_{\mbox{初始}}$
  2. 字体控制,符号:\displaystyle,如:$\displaystyle \frac{x+y}{y+z}$
  3. 下划线符号,符号:\underline,如:$\underline{x+y}$
  4. 标签,符号\tag{数字},如:$\tag{11}$
  5. 上大括号,符号:\overbrace{算式},如:$\overbrace{a+b+c+d}^{2.0}$
  6. 下大括号,符号:\underbrace{算式},如:$a+\underbrace{b+c}_{1.0}+d$
  7. 上位符号,符号:\stacrel{上位符号}{基位符号},如:$\vec{x}\stackrel{\mathrm{def}}{=}{x_1,\dots,x_n}$

占位符

  1. 两个quad空格,符号:\qquad,如:$x \qquad y$
  2. quad空格,符号:\quad,如:$x \quad y$
  3. 大空格,符号\,如:$x \ y$
  4. 中空格,符号\:,如:$x : y$
  5. 小空格,符号\,,如:$x , y$
  6. 没有空格,符号``,如:$xy$
  7. 紧贴,符号\!,如:$x ! y$

定界符与组合

  1. 括号,符号:()\big(\big) \Big(\Big) \bigg(\bigg) \Bigg(\Bigg),如:$()\big(\big) \Big(\Big) \bigg(\bigg) \Bigg(\Bigg)$
  2. 中括号,符号:[],如:$[x+y]$
  3. 大括号,符号:\{ \},如:${x+y}$
  4. 自适应括号,符号:\left \right,如:$\left(x\right)$,$\left(x{yz}\right)$
  5. 组合公式,符号:{上位公式 \choose 下位公式},如:${n+1 \choose k}={n \choose k}+{n \choose k-1}$
  6. 组合公式,符号:{上位公式 \atop 下位公式},如:$\sum_{k_0,k_1,\ldots>0 \atop k_0+k_1+\cdots=n}A_{k_0}A_{k_1}\cdots$
阅读全文 »

SpringBoot整合SpringCache

SpringCache整合多种数据源,使用Aop提供业务缓存的使用,使用注解既可以实现简单的应用缓存配置。

Spring官方参考文档

1、引入依赖POM

1.1、引入SpringBoot-Cache

1
2
3
4
5
6
//引入SpringCache官方Starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
//使用SpringCache中什么样的数据源就引入什么类型的启动器

1.2、引入第三方的缓存Jar依赖

根据SpringBoot CacheAutoConfiguraton分析可知,其自动配置了很多缓存的数据源:

image-20220411210146061

而这些数据自动配置类,在导入响应的Jar依赖之后会自动配置,这里使用Redis作为缓存中间件。

1
2
3
4
5
//父工程为SpringBoot自动管理依赖版本
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
阅读全文 »

MyBatis整合SpingBoot

一、引入SprngBoot0-Starter-parent依赖

1
2
3
4
5
6
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
<relativePath/>
</parent>

二、引入MybatisPlus以及SpringBoot基础框架

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!--mysql数据库连接驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!--德鲁伊数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
</dependencies>

三、配置数据库连接

1
2
3
4
5
6
spring:
datasource:
username: 账户
password: 密码
url: jdbc:mysql://连接地址:3306/数据库名称?useUnicode=true&characterEncoding=utf8
driver-class-name: com.mysql.cj.jdbc.Driver

四、配置启动配置类

1、配置分页

2、配置乐观锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@Configuration //配置类
@EnableTransactionManagement //开启事务管理器
@MapperScan(basePackages = "扫描的Mapper包名")
public class MybatisConfig {
/**
* 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
//设置Mybatis拦截器
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();


//设置分页拦截器类型---(数据库类型)
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
//配置溢出总页数后是否进行处理
paginationInnerInterceptor.setOverflow(true);
//单页分页条数限制
paginationInnerInterceptor.setMaxLimit(1000L);
//其他配置参照分页插件拦截器源码
interceptor.addInnerInterceptor(paginationInnerInterceptor);

//设置乐观锁
/*
1、支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
2、整数类型下 newVersion = oldVersion + 1 newVersion 会回写到 entity 中
3、仅支持 updateById(id) 与 update(entity, wrapper) 方法
4、在 update(entity, wrapper) 方法下, wrapper 不能复用!!!
*/
OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();
interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);


//防止全表更新插件
BlockAttackInnerInterceptor blockAttackInnerInterceptor = new BlockAttackInnerInterceptor();
interceptor.addInnerInterceptor(blockAttackInnerInterceptor);

return interceptor;
}

}
阅读全文 »