请教大佬们一个问题, 对于资源占用类的需求大家怎么设计的了,例如数据库存储了一批设备信息,每个设备只能被一个用户占用,用完释放了才能被继续占用。我目前的做法是,给设备表加了一个 status 状态字段,先获取一台空闲设备,然后去更新状态字段,更新成功则返回,更新失败就继续循环,原理就是利用数据库锁,但是实际使用中发现有些设备会释放失败,一直处于忙碌中,占用正常,没有出现重复占用情况,有什么改善方案吗
1
Jooooooooo 2022-10-31 16:55:41 +08:00
有个简单的办法是, 兜底释放, 占用时间是有上限的. 到了上限时间一定会被释放. (可以搞个定时任务扫到期的任务, 就算是某一次释放失败了下一次也能成功)
但上面这个方法时效性不够, 而且某些场景下不适用 时效性强一点可以考虑兜底去补偿. 方法也很多, 一种可行的是, 释放后, 直接发一个延迟检查的消息, 短暂时间后收到检查消息看看是不是真的释放了, 如果没有再释放一次, 并且再发这个检查消息, 比如重复发三次. 如此一来还会无法得到失败的场景就基本不存在了. (可以再结合上面第一种兜底到时间一定释放, 保证万无一失) 这里面可再做改进的是, 可以当数据库更新失败后(无论是返回为 0 或者抛了异常), 可以原地直接重试释放, 然后再发检查消息 这里面有个注意的点, 需要有个标记记录, 只能释放自己获得的资源, 否则会出现, A 释放了资源, B 获取了资源, A 获得延迟检查消息, 发现资源被占用, 把 B 占用的资源释放了. 可以多一个字段直接是一串随机数(uuid 就行), 延迟检查消息要带着这个 uuid 去释放, 对不上说明已经被其他人重新占用了, 不用再释放. |
2
lx91714 OP @Jooooooooo 感谢解答,让我有点头绪了,谢谢啦
|