目录
a.实现ApplicationRunner接口,在项目启动时,初始化数据,动态创建表,动态创建存储过程
b.运用springboot自动装配的功能,实现通过配置@ConditionalOnProperty,装配不同的序列生成实现类
a.序列存储表中增加一列version字段,查询某条记录,然后更新version字段,如果更新成功则获取序列有效,如果更新失败,则继续或许,继续更新,采用自旋,乐观锁,完成序列递增获取
一.文章结构
1.实现方式(基于redis,存储过程,乐观锁)
2.项目集成(开箱即用,maven引入,加入yml)
3.多线程测试结果展示
4.实现原理剖析(乐观锁,自旋高效实现递增序列获取;springboot实现自定义starter)
5.源码地址下载
二.项目递增序列组件集成
1.maven引入
<dependency>
<groupId>com.zenglx.assembly.increasingSequence</groupId>
<artifactId>starter</artifactId>
</dependency>
2.配置
com:
zenglx:
assembly:
sequenceGenerator:
type: redis # 序列生成类型 redis,procedure,lock三种
tableName: seq_table # 存储序列的表,默认optimistic_lock_sequence
isAutoCreate: 1 #是否自动创建 表和存储过程,默认自动创建
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: kmjs
password: kmjs
url: jdbc:mysql://127.0.0.1:3306/kmjsdb?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
druid:
initialSize: 15
minIdle: 5
maxActive: 30
maxWait: 60000
redis:
host: 127.0.0.1
port: 6379
max-redirects: 3
lettuce:
pool:
max-idle: 500 # 连接池中的最大空闲连接,默认值也是8。
min-idle: 50 #连接池中的最小空闲连接,默认值也是0。
max-active: 2000 # 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
max-wait: 1000 # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionExceptionid.type: redisplus
三.测试结果展示
1.基于redis实现分布式递增序列
a.测试代码
package com.zenglx.demo;
/**
* 服务启动入口
* @author zlx
*/
@RestController
public class AssemblyDemoTest {
@Autowired
private SequenceGeneratorApi sequenceGeneratorApi;
@GetMapping("/test")
public String test() {
final CountDownLatch latch = new CountDownLatch(30);
for(int i=0;i<10;i++){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程名:"+Thread.currentThread().getName()
+":"+sequenceGeneratorApi.nextId("default-lock"));
}
});
thread.start();
}
return null;
}
}
b.项目配置
server:
port: 8888
spring:
redis:
host: 127.0.0.1
port: 6379
max-redirects: 3
lettuce:
pool:
max-idle: 500 # 连接池中的最大空闲连接,默认值也是8。
min-idle: 50 #连接池中的最小空闲连接,默认值也是0。
max-active: 2000 # 如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
max-wait: 1000 # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionExceptionid.type: redisplus
com:
zenglx:
assembly:
sequenceGenerator:
type: redis -- type为递增序列生成类型 redis,procedure,lock三种
c.测试结果展示
2.基于数据库存储过程的测试
a.项目配置
server:
port: 8888
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: kmjs
password: kmjs
url: jdbc:mysql://127.0.0.1:3306/kmjsdb?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
druid:
initialSize: 15
minIdle: 5
maxActive: 30
maxWait: 60000
com:
zenglx:
assembly:
sequenceGenerator:
type: procedure
tableName: seq_table # 存储序列的表
isAutoCreate: 1 #是否自动创建 表和存储过程
b.测试结果展示
3.基于数据库乐观锁的测试
a.项目配置
server:
port: 8888
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: kmjs
password: kmjs
url: jdbc:mysql://127.0.0.1:3306/kmjsdb?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
druid:
initialSize: 15
minIdle: 5
maxActive: 30
maxWait: 60000
com:
zenglx:
assembly:
sequenceGenerator:
type: lock
tableName: seq_table # 存储序列的表
isAutoCreate: 1 #是否自动创建 表和存储过程
2.测试结果展示
四.实现原理
1.开箱即用,maven引入,加入配置即可
a.实现ApplicationRunner接口,在项目启动时,初始化数据,动态创建表,动态创建存储过程
b.运用springboot自动装配的功能,实现通过配置@ConditionalOnProperty,装配不同的序列生成实现类
2.乐观锁的实现原理
a.序列存储表中增加一列version字段,查询某条记录,然后更新version字段,如果更新成功则获取序列有效,如果更新失败,则继续或许,继续更新,采用自旋,乐观锁,完成序列递增获取
五.源码下载
springboot-component: 基于springboot的starter组件,包括分布式递增序列,防重复提交