mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
fix(cron): restore ShedLock DB-time for dialects that support it
The KingbaseES change removed usingDbTime() unconditionally, which made every deployment (MySQL/H2/PostgreSQL) fall back to app-server time for distributed lock timing — reintroducing node clock-drift risk in multi-instance setups. Re-enable usingDbTime() for databases in ShedLock's built-in dialect map and skip it only for KingbaseES, which is not covered and would otherwise throw at lock acquisition.
This commit is contained in:
parent
25a83ad858
commit
ed6eac310a
@ -9,6 +9,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
|
||||
/**
|
||||
* RFC-03 Lane G2 — distributed lock provider for the cron scheduler.
|
||||
@ -37,15 +38,38 @@ public class ShedLockConfig {
|
||||
|
||||
@Bean
|
||||
public LockProvider lockProvider(DataSource dataSource) {
|
||||
log.info("[ShedLock] Initializing JDBC LockProvider for cron scheduling");
|
||||
return new JdbcTemplateLockProvider(
|
||||
boolean useDbTime = supportsDbTime(dataSource);
|
||||
log.info("[ShedLock] Initializing JDBC LockProvider for cron scheduling (usingDbTime={})", useDbTime);
|
||||
|
||||
JdbcTemplateLockProvider.Configuration.Builder builder =
|
||||
JdbcTemplateLockProvider.Configuration.builder()
|
||||
.withJdbcTemplate(new JdbcTemplate(dataSource))
|
||||
.withTableName("shedlock")
|
||||
// usingDbTime() removed — KingbaseES not in ShedLock's
|
||||
// built-in dialect map; app-server time is sufficient
|
||||
// given lockAtMostFor=PT30M
|
||||
.build()
|
||||
);
|
||||
.withTableName("shedlock");
|
||||
|
||||
// Server-side DB time (NOW()) avoids node clock drift across a
|
||||
// multi-instance deployment. ShedLock's built-in db-time dialect map
|
||||
// covers MySQL/MariaDB, PostgreSQL, H2, etc. KingbaseES is not in that
|
||||
// map, so usingDbTime() would throw there — fall back to app-server
|
||||
// time for it, which is safe given lockAtMostFor=PT30M.
|
||||
if (useDbTime) {
|
||||
builder.usingDbTime();
|
||||
}
|
||||
return new JdbcTemplateLockProvider(builder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true when the DataSource's database is covered by ShedLock's
|
||||
* built-in db-time dialect map. Only KingbaseES is excluded; on any
|
||||
* detection failure we conservatively return false so the lock provider
|
||||
* never throws at acquisition time.
|
||||
*/
|
||||
private boolean supportsDbTime(DataSource dataSource) {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
String product = connection.getMetaData().getDatabaseProductName().toLowerCase();
|
||||
return !product.contains("kingbase");
|
||||
} catch (Exception e) {
|
||||
log.warn("[ShedLock] Could not detect database product; using app-server time: {}", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user