我遇到了这个具有挑战性的场景,其中事务在执行批量更新查询时被 Microsfoft sql server 锁定。
我看到了这个错误。
事务(进程 ID 293)与另一个进程在锁资源上死锁,并已被选为死锁牺牲品。重新运行事务。; 嵌套异常是 com.microsoft.sqlserver.jdbc.SQLServerException:事务(进程 ID 293)在锁资源上与另一个进程死锁,并已被选为死锁牺牲品。
我的批量更新查询:
jdbcTemplate.batchUpdate(purgeQueryArray)
如果超过 7 天,我有 7-8 个表需要清除其数据。现在,在较低环境的情况下,由于数据量低,所以它工作正常。在生产中,每个表中的数据多达 300k 到 500k。在删除这么多记录时,执行 spring jdbc 查询的 shedlock 任务最终陷入死锁。相同操作的 API 工作正常,但在不同时间执行,因此不确定计划任务运行时的负载。
@Scheduled(cron = "${scheduler.expression}", zone = "GMT")
@SchedulerLock(name = "SCHEDULER_LOCK", lockAtLeastFor = "10S", lockAtMostFor = "5M")
public void purge() {
// prepare array of queries purgeQueryArray
jdbcTemplate.batchUpdate(purgeQueryArray)
}
Shedlock表数据:
SCHEDULER_LOCK 2020-10-21 00:00:15 2020-10-21 00:00:00 tomcat-406116080-2-521278230
虽然我给出了 lockAtMostFor=5M ,但看起来 lock_until 显示 15 秒,这很奇怪。这可能是原因吗?因为生产数据量需要 1-2 分钟。
任何建议将不胜感激
编辑:
DELETE FROM BATCH_STEP_EXECUTION_CONTEXT WHERE STEP_EXECUTION_ID IN (SELECT BE.STEP_EXECUTION_ID FROM BATCH_STEP_EXECUTION BE
join BATCH_STEP_EXECUTION_CONTEXT BEC on BE.STEP_EXECUTION_ID = BEC.STEP_EXECUTION_ID
where CAST(LAST_UPDATED as date) < DATEADD(day, -7, GETDATE()));
DELETE FROM BATCH_STEP_EXECUTION WHERE JOB_EXECUTION_ID IN (SELECT JOB_EXECUTION_ID FROM BATCH_JOB_EXECUTION
where CAST(LAST_UPDATED as date) < DATEADD(day, -7, GETDATE()));
DELETE FROM BATCH_JOB_EXECUTION_CONTEXT WHERE JOB_EXECUTION_ID IN (SELECT JOB_EXECUTION_ID FROM BATCH_JOB_EXECUTION
where CAST(LAST_UPDATED as date) < DATEADD(day, -7, GETDATE()));
DELETE FROM BATCH_JOB_EXECUTION_PARAMS WHERE JOB_EXECUTION_ID IN (SELECT JOB_EXECUTION_ID FROM BATCH_JOB_EXECUTION
where CAST(LAST_UPDATED as date) < DATEADD(day, -7, GETDATE()));
DELETE FROM BATCH_JOB_EXECUTION WHERE CAST(LAST_UPDATED as date) < DATEADD(day, -7, GETDATE());
DELETE FROM BATCH_JOB_INSTANCE WHERE JOB_INSTANCE_ID NOT IN (SELECT JOB_INSTANCE_ID FROM BATCH_JOB_EXECUTION);
提前致谢