如何精准控制业务合同到期后不再发生业务?还是邻家系统做得好!
本文以“业务合同”为例,来探讨特定应用场景的程序设计方案。
业务合同数据包含生效日 和 到期日。 当超出合同的到期日以后,合同所涉及的业务就不能再做了。
这是企业应用系统中常见的应用场景。
即:
- 业务发生时,要判断对应的合同是否有效
- 合同到期时,要标记为“已到期”
我们先定义合同的数据结构:
名称 | 类型 | 说明 |
---|---|---|
contactId | int | 合同id |
effectiveTime | date | 生效日 |
expiredTime | date | 到期日 |
status | char | 合同状态。INIT:初始-EFFECTIVE:生效中-EXPIRED:已到期 |
接着,我们定义合同服务类
interface contactService {
// 判断合同是否有效
boolean contactIsEffective(contactId);
// 标记到期合同的状态为“已到期”
void processExpiredcontacts();
}
当合同到期后,系统要标记合同的状态为“已到期”,我们的程序怎么实现呢?
这里需要考虑的一个重点是,要保证上面的第一点“到期的合同不能再发生业务”,否则就是系统bug了。
使用定时任务,大家自然而然会想到。
每天凌晨0:00定时跑批,检查系统里是否有当日到期的合同,到期则将status由“EFFECTIVE”改为“EXPIRED”。
这里会存在一个问题,就是无法精准控制合同有效期的问题。毕竟定时任务执行也有耗时的,在这期间被调用的 contactIsEffective(contactId)
会存在错误地返回true
的情况。
这个问题怎么解决?
更坏的情况,假如,合同到期的粒度不是date,而是更细粒度的hour/minute,例如 某合同的到期时间是"2025-02-21 17:20:00",上面的定时任务,就更吃力了。
所以,怎么解决呢?
邻家系统一招搞定,简直不要太哇塞!
在 contactService#contactIsEffective 方法里,获取指定的合同记录后,当 status=EFFECTIVE 时,则再判断一下 expiredTime, 如果 expiredTime≥当前时间,则触发合同状态的变更,并返回false。(注:这里只谈程序实现思路,对于并发调用的控制等方面,本文不做讨论)
是不是很简单?是的,亲爱的你,有没有想起缓存技术中,缓存过期的惰性删除策略呢?是不是有异曲同工之妙呢!
当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!--buguge
本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/buguge/p/18742255