锁
Lock
高级通用锁(Lock)是一种协调并发操作的机制:一项操作占有锁期间,其他争用同一把锁的操作需要等待或放弃。它用来避免多个请求同时处理同一份资源,例如多个服务实例同时执行一项定时任务。
你可能会说:「我把后台部署成多个实例后,同一个定时任务有时会跑好几遍,能让它一次只由一个实例执行吗?」
读之前建议先了解(这是一个高级概念)
动手看看定时报表由谁来生成
1
到了生成报表的时间,两个服务实例都来申请同一把任务锁;谁先拿到,谁才能开始执行。
要点锁是怎样协调并发操作的?
- 1
先确定要保护哪份资源
锁通常对应一项具体资源,而不是整个网站。比如导出任务可以按任务 ID 加锁:处理同一个任务的请求互相争用,处理不同任务的请求则可以并行。锁的范围越大,无关操作越容易被挡住。
- 2
拿到锁后再执行关键操作
多个操作都想修改同一份数据时,只有拿到锁的那个先进入关键操作;没拿到的可以等待、重试或直接返回。因为这些选择会影响响应时间和用户看到的结果,所以你需要和 AI 说清楚希望怎么处理争用。
- 3
释放锁还要考虑异常退出
操作结束后要释放锁,但服务也可能中途崩溃。跨实例使用锁时,通常会设置过期时间,并确认只由持有者释放;如果任务可能跑得比过期时间更久,还得处理锁提前失效后两个实例同时工作的风险。
容易混淆的地方
锁解决的是“谁能同时进入这段操作”,事务解决的是“一组数据库改动能否一起成功或回滚”。事务内的行锁也是锁的一种,但给代码加一把锁并不会让多次写入自动成为事务。幂等则让重复请求产生可控结果;即使有锁,请求在锁释放后仍可能重来,所以两者常要配合。
什么时候用
适合用
- 后台部署了多个实例,却只想让一项定时结算任务在同一时刻由一个实例执行。
- 同一用户的报告生成成本很高,想避免多个并发请求重复生成同一份报告。
- 多个工作进程会更新同一份共享资源,且关键操作无法用单条数据库语句完成。
不适合用
- 只是给单条记录的数值加一,可以先用数据库原子更新,不必在应用层另加锁。
- 只想防止重复提交创建两笔订单,优先用幂等键和数据库唯一约束处理重试。
- 只是想限制接口每分钟可请求的次数,用速率限制;锁解决的不是累计请求量。
练一练选一个答案,看看解释
你的后台有三个实例,都运行同一项每晚生成报表的定时任务。一次生成可能持续十分钟,而且某个实例可能中途退出。你会让 AI 怎么设计?
让 AI 帮你做复制给 AI Agent 直接用
请检查现有定时任务在多实例部署下是否会并发执行。若需要锁,请按任务 ID 设计跨实例协调,说明获取失败时怎么处理、锁过期与续期策略、如何避免误释放,并补上重复执行时的数据保护与测试。