1、背景
数据库中存在一个预约时间表(t_reserve),和一个正在生效的时间表(t_time)
根据业务需求,在t_reserve表中配置多个不同的时间,然后定时去更新t_time表
2、问题
因为应用是集群部署,需要考虑
1)、多进程的任务锁抢占
2)、当抢占到任务锁的应用挂了,宕机的情况,没有释放任务锁,造成死锁
3)、集群部署,无法保证每台应用同时启动定时任务,多个定时任务的触发点会被错开,定时任务的间隔执行时间无法保证
3、实现
需要设计一个定时计划表(t_job)
job_name | job__status | start_time | end_time | interval |
---|---|---|---|---|
任务 | 运行状态 0-未运行 1-运行中 |
开始时间 | 结束时间 | 任务锁过期时间 |
job | 0 | 60 |
3.1)、任务锁的实现(列举当时想到的三种实现)
3.1.1)、本来打算使用forupdate实现悲观锁
a)、查询t_job,看是否有任务,任务是否在执行中
select * from t_job where job_name='job' forupdate; #行锁,会锁住t_job表的job这一行
forupdate锁表规则:
当有明确指定唯一行(如主键),那么就是行锁,其他行的数据,别的事务还是可以操作该表的
指定行不明确(如不等于某个主键值,会返回好多数据),那么就是表锁了,这时候锁了整个表,其他事务无法操作该表
b)、这儿又需要分两种情况 肯定会更新成功,悲观锁,同个只有同个时间可以操作
b.1)、当前查询到没有任务在执行
直接更新t_job表,将job_status置为1,表示抢占到任务锁