? ? ? ? Lock4j是一个分布式锁组件,其提供了多种不同的支持以满足不同性能和环境的需求。 简单易用,功能强大,扩展性强。支持redission,redisTemplate,zookeeper。可混用,支持扩展。 ? ? ? ? 本文演示SpringBoot整合lock4j,并基于redission和大家一起学习基本使用。
一、项目搭建 ? ? 新建一个SpringBoot项目,引入依赖:
<properties>
<java.version>1.8</java.version>
</properties>
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>lock4j-redisson-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>8.0.22</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
二、配置文件及建表语句
①配置文件:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
username: ****
password: ****
redis:
host: localhost
port: 6379
server:
port: 9090
②建表语句:
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`province` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`city` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
`point` int(8) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 0 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
三、编码实现
?? ?①访问层
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("test")
public void test(@RequestBody @Validated User user){
userService.doLock4jTest(user);
}
}
? ?②服务层
public interface UserService {
void doLock4jTest(User user);
}
@Service
@Slf4j
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
@Lock4j(keys = {"#user.id"})
public void doLock4jTest(User user) {
Integer sum = userMapper.getSum();
log.info("---sum:{}",sum);
if (null == sum || sum <= 18){
User u = new User();
u.setName("test");
u.setProvince("上海市");
u.setCity("浦东新区");
u.setPoint(2);
userMapper.insert(u);
}
}
}
? ?③持久层
public interface UserMapper extends BaseMapper<User> {
Integer getSum();
}
? ?④实体层
@NoArgsConstructor
@AllArgsConstructor
@Data
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
private Integer id;
private String name;
private String province;
private String city;
private Integer point;
}
⑤映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
<resultMap type="com.example.demo.entity.User" id="BaseMap">
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="province" column="province"/>
<result property="city" column="city"/>
<result property="point" column="point"/>
</resultMap>
<select id="getSum" resultType="java.lang.Integer" >
SELECT sum(point) FROM `user`;
</select>
</mapper>
?⑥启动类
@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class Lock4jDemoApplication {
public static void main(String[] args) {
SpringApplication.run(Lock4jDemoApplication.class, args);
}
}
四、并发模拟测试及说明
①Postman模拟并发40次:
②控制台日志及数据库插入数据:
2022-07-14 22:26:45.936 INFO 16700 --- [nio-9090-exec-2] c.e.demo.service.impl.UserServiceImpl : ---sum:null
2022-07-14 22:26:46.161 INFO 16700 --- [nio-9090-exec-3] c.e.demo.service.impl.UserServiceImpl : ---sum:2
2022-07-14 22:26:46.307 INFO 16700 --- [nio-9090-exec-4] c.e.demo.service.impl.UserServiceImpl : ---sum:4
2022-07-14 22:26:46.443 INFO 16700 --- [nio-9090-exec-5] c.e.demo.service.impl.UserServiceImpl : ---sum:6
2022-07-14 22:26:46.552 INFO 16700 --- [nio-9090-exec-6] c.e.demo.service.impl.UserServiceImpl : ---sum:8
2022-07-14 22:26:46.674 INFO 16700 --- [nio-9090-exec-7] c.e.demo.service.impl.UserServiceImpl : ---sum:10
2022-07-14 22:26:46.814 INFO 16700 --- [nio-9090-exec-8] c.e.demo.service.impl.UserServiceImpl : ---sum:12
2022-07-14 22:26:46.958 INFO 16700 --- [nio-9090-exec-9] c.e.demo.service.impl.UserServiceImpl : ---sum:14
2022-07-14 22:26:47.080 INFO 16700 --- [io-9090-exec-10] c.e.demo.service.impl.UserServiceImpl : ---sum:16
2022-07-14 22:26:47.222 INFO 16700 --- [nio-9090-exec-1] c.e.demo.service.impl.UserServiceImpl : ---sum:18
2022-07-14 22:26:47.361 INFO 16700 --- [nio-9090-exec-2] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:47.487 INFO 16700 --- [nio-9090-exec-3] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:47.623 INFO 16700 --- [nio-9090-exec-4] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:47.749 INFO 16700 --- [nio-9090-exec-5] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:47.872 INFO 16700 --- [nio-9090-exec-6] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:48.002 INFO 16700 --- [nio-9090-exec-7] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:48.107 INFO 16700 --- [nio-9090-exec-8] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:48.222 INFO 16700 --- [nio-9090-exec-9] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:48.339 INFO 16700 --- [io-9090-exec-10] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:48.464 INFO 16700 --- [nio-9090-exec-1] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:48.587 INFO 16700 --- [nio-9090-exec-2] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:48.681 INFO 16700 --- [nio-9090-exec-3] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:48.850 INFO 16700 --- [nio-9090-exec-4] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:48.978 INFO 16700 --- [nio-9090-exec-5] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:49.086 INFO 16700 --- [nio-9090-exec-6] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:49.194 INFO 16700 --- [nio-9090-exec-7] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:49.318 INFO 16700 --- [nio-9090-exec-8] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:49.458 INFO 16700 --- [nio-9090-exec-9] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:49.552 INFO 16700 --- [io-9090-exec-10] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:49.676 INFO 16700 --- [nio-9090-exec-1] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:49.770 INFO 16700 --- [nio-9090-exec-2] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:49.878 INFO 16700 --- [nio-9090-exec-3] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:49.972 INFO 16700 --- [nio-9090-exec-4] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:50.082 INFO 16700 --- [nio-9090-exec-5] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:50.190 INFO 16700 --- [nio-9090-exec-6] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:50.300 INFO 16700 --- [nio-9090-exec-7] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:50.410 INFO 16700 --- [nio-9090-exec-8] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:50.535 INFO 16700 --- [nio-9090-exec-9] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:50.660 INFO 16700 --- [io-9090-exec-10] c.e.demo.service.impl.UserServiceImpl : ---sum:20
2022-07-14 22:26:50.784 INFO 16700 --- [nio-9090-exec-1] c.e.demo.service.impl.UserServiceImpl : ---sum:20
③?断点进入方法,发现Redis中产生数据:
④?业务逻辑执行完毕,Redis中产生的数据被删除。
? ? ? ? 整个流程是利用redis加分布式锁,然后处理业务逻辑,再释放锁。
????????至此,SpringBoot整合Lock4j演示完毕。有兴趣的读者可以尝试基于redisTemplate,zookeeper的实现方式。
|