部署环境说明:
服务器:
192.168.66.100(服务器A) nginx:部署前端项目、配置反向代理 Mysql:主从复制结构中的主库 192.168.66.101(服务器B) jdk:运行Java项目 git:版本控制工具 maven:项目构建工具 jar:SpringBoot项目打包成jar包基于内置Tomcat运行 Mysql:主从复制结构中的从库 192.168.66.100(服务器C) Redis:缓存中间件
配置完记得 nginx -s reload 一下,然后再访问就可以了
Swagger 注解:
1、@Api:用在请求的类上,例如 Controller,表示对类的说明
2、@ApiModel:用在类上,通常是实体类,表示一个返回响应数据的信息
3、@ApiModelProperty:用在属性上,描述响应类的属性
4、@ApiOperation:用在请求方法上,说明方法的用途、作用
5、@ApilmplicitParams:用在请求的方法上,表示一组参数说明
6、@ApilmplicitParam:用在 @ApilmplicitParams 注解中,指定一个请求参数的各个方面
MVCC:
全称 Multi-Vwesion Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为 MySQL 实现 MVCC 提供了一个非阻塞读功能。MVCC 的具体实现,还需要依赖于数据库记录中的三个隐式字段、undo log 日志、readView。
当前读:
读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:select…lock in share mode (共享锁),select…for update、insert、delete (排他锁) 都是一种当前读
快照读:
简单的 select (不加锁) 就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。
- Read Committed:每次 select,都生成一个快照读。
- Repeatable Read:开启事务后第一个 select 语句才是快照读的地方。
- Serializable:快照读会退化为当前读。
MVCC 实现原理:
记录中的隐藏字段:
- DB_TRX_ID:最近修改事务 ID,记录插入这条记录或最后一次修改该记录的事务 ID。
- DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本,用于配合 undo log,指向上一个版本。
- DB_ROW_ID:隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段。如果有主键,那么将没有这个字段
id | age | name |
---|---|---|
1 | 1 | tom |
3 | 3 | cat |
实际上是:
id | age | name | DB_TRX_ID | DB_ROLL_PTR | DB_ROW_ID |
---|---|---|---|---|---|
undo log:
- 回滚日志,在 insert、update、delete 的时候产生的便于数据回滚的日志。
- 当 insert 的时候,产生的 undo log 日志只在回滚时需要,在事务提交后,可被立即删除
- 而 update、delete 的时候,产生的 undo log 日志不仅在回滚时需要,在快照读时也需要,不会立即被删除
undo log 版本链条:
不同事务或相同事务对同一条记录进行修改,会导致该记录的 undo log 生成一条记录版本链条,链条的头部是最新的旧纪录,链表尾部是最早的旧纪录。
readview:
- Readview (读视图) 是快照读 SQL 执行是 MVCC 提取数据的依据,记录并维护系统当前活跃的事务 (未提交的) id。
- ReadView 中包含了四个核心字段:
- m_ids:当前活跃的事务 ID 集合
- min_trx_id:最小活跃事务 ID
- max_trx_id:预分配事务 ID,当前最大事务 ID+1 (因为事务 ID 是自增的)
- creator_trx_id:ReadView 创建者的事务 ID
版本链数据访问规则:
trx_id:代表是当前事务 ID
- trx_id creator_trx_id ? :可以访问该版本 -> 成立,说明数据是当前这个事务更改的
- trx_id <min_trx_id ? : 可以访问该版本 -> 成立,说明数据已经提交了
- trx_id max_trx_id ? :不可以访问该版本 -> 成立,说明该事务是在 ReadView 生成后才开启
- min_trx_id <= trx_id <= max_trx_id ? :如果 trx_id 不再 m_ids 中是可以访问该版本的 -> 成立,说明数据已经提交
不同的隔离级别,生成的 ReadView 的时机不同:
- READ COMMITTED : 在事务中每一次执行快照读时生成 ReadView。
- REPEATABLE READ:仅在事务中第一次执行快照读时产生 ReadView,后续复用该 ReadView。
MybatisPlus:
- 新增:int insert (T t)
- 删除:int deleteById (Serializable id)
- 修改:int updateById (T t)
- 根据 id 查询:T selectById (Serializable id)
- 查询全部:List
selectList() - 分页查询:IPage
selectPage(IPage page) - 按条件查询:IPage
selectPage(Wrapper queryWrapper)
lombok:
常用注解:
- @Getter/@Setter: 为所有属性提供 get/set 方法
- @ToString: 会给类自动生成易阅读的 toString 方法
- @EqualsAndHashCode: 根据类所拥有的非静态字段自动重写 equals 方法和 hashCode 方法
- @Data: 提供了更综合的生成代码功能 (@Getter+@Setter+@ToString+@EqualsAndHashCode)
- @NoArgsConstructor: 为实体类生成无参的构造方法
- @AllArgsConstructor: 为实体类生成除了 static 修饰的字段之外有各参数的构造器方法
分页查询:
配置分页查询 bean:
-------------------------------------------- MpConfig.java @Configuration public class MpConfig{ @Bean public MybatisPlusInterceptor mpInterceptor(){ //1、定义Mp拦截器 MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor(); //2、添加具体拦截器 mpInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return mpInterceptor; } } -------------------------------------------- void testGetByPage(){ Ipage page = new Page(1,2); //Page(current:1,size:2) userDao.selectPage(page,null); System.out.pringtln("当前页码值:"+page.getCurrent()); System.out.pringtln("每页显示数:"+page.getSize()); System.out.pringtln("一共多少页:"+page.getPages()); System.out.pringtln("一共多少条数据:"+page.getTotal()); System.out.pringtln("数据:"+page.getRecords()); } -------------------------------------------- 调日志: application.yml #开启mp的日志(输出到控制台) mybatis-plus: configuration: log-impl:org.apache.ibatis.logging.stdout.StdOutImpl --------------------------------------------