基于 Spring Boot + MyBatis + DM8 的分布式锁
project-root/
├── src/
│   └── main/
│       ├── java/com/example/demo/
│       │   ├── DemoApplication.java
│       │   ├── config/
│       │   │   └── MyBatisConfig.java
│       │   ├── entity/
│       │   │   └── ScheduledLock.java
│       │   ├── mapper/
│       │   │   └── ScheduledLockMapper.java
│       │   ├── service/
│       │   │   └── TaskLockService.java
│       │   └── task/
│       │       └── DemoScheduledTask.java
│       └── resources/
│           ├── application.yml
│           └── mapper/ScheduledLockMapper.xml
├── pom.xml// pom.xml
<project><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>dm8-task-lock-demo</artifactId><version>1.0.0</version><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.1</version></dependency><dependency><groupId>com.dameng</groupId><artifactId>DmJdbcDriver18</artifactId><version>8.1.2.49</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-scheduling</artifactId></dependency></dependencies>
</project>// application.yml
spring:datasource:url: jdbc:dm://localhost:5236/DAMENGusername: your_userpassword: your_passworddriver-class-name: dm.jdbc.driver.DmDrivermybatis:mapper-locations: classpath*:mapper/*.xmlconfiguration:map-underscore-to-camel-case: true// entity/ScheduledLock.java
@Data
public class ScheduledLock {private String lockName;private LocalDateTime lockUntil;private LocalDateTime lockedAt;private String lockedBy;
}// mapper/ScheduledLockMapper.java
@Mapper
public interface ScheduledLockMapper {ScheduledLock selectLock(@Param("lockName") String lockName);void insertLock(ScheduledLock lock);int updateIfExpired(ScheduledLock lock);
}// mapper/ScheduledLockMapper.xml
<mapper namespace="com.example.demo.mapper.ScheduledLockMapper"><select id="selectLock" resultType="com.example.demo.entity.ScheduledLock">SELECT * FROM scheduled_lock WHERE lock_name = #{lockName}</select><insert id="insertLock">INSERT INTO scheduled_lock (lock_name, lock_until, locked_at, locked_by)VALUES (#{lockName}, #{lockUntil}, #{lockedAt}, #{lockedBy})</insert><update id="updateIfExpired">UPDATE scheduled_lockSET lock_until = #{lockUntil},locked_at = #{lockedAt},locked_by = #{lockedBy}WHERE lock_name = #{lockName} AND lock_until < SYSDATE</update>
</mapper>// service/TaskLockService.java
@Service
public class TaskLockService {@Autowired ScheduledLockMapper mapper;private final String instanceId = InetAddress.getLocalHost().getHostName();public boolean tryLock(String lockName, Duration holdTime) {LocalDateTime now = LocalDateTime.now();LocalDateTime until = now.plus(holdTime);ScheduledLock lock = new ScheduledLock();lock.setLockName(lockName);lock.setLockUntil(until);lock.setLockedAt(now);lock.setLockedBy(instanceId);int updated = mapper.updateIfExpired(lock);if (updated > 0) return true;ScheduledLock existing = mapper.selectLock(lockName);if (existing == null) {mapper.insertLock(lock);return true;}return instanceId.equals(existing.getLockedBy()) && existing.getLockUntil().isAfter(now);}
}// task/DemoScheduledTask.java
@Slf4j
@Component
public class DemoScheduledTask {@Autowired TaskLockService lockService;@Scheduled(cron = "0 */1 * * * ?")public void runClusterSingletonTask() {if (!lockService.tryLock("demo-task", Duration.ofMinutes(2))) {log.info("跳过任务,本机未抢到锁");return;}log.info("本机获得锁,执行定时任务");// 执行任务逻辑}
}// SQL 建表
CREATE TABLE scheduled_lock (lock_name VARCHAR(100) PRIMARY KEY,lock_until TIMESTAMP,locked_at TIMESTAMP,locked_by VARCHAR(100)
);
特点:
- 
支持多实例部署,只有一台机器能执行任务 
- 
使用达梦数据库做分布式锁,自动过期无需手动释放 
- 
基于 MyBatis,简单清晰,易于扩展 
- 
配置友好,完全可运行、可集成 
包含模块:
- 
scheduled_lock 建表 SQL 
- 
实体类 + Mapper + XML + Service 
- 
一个最小定时任务示例(每分钟执行一次) 
- 
YML 配置连接 DM8 
