搜索

查找主题、作者或分类。

定时任务不只要防重:租约与 Fencing Token 的最小实现这项补充解决了当前讨论尚未覆盖的“提交结果不确定”问题,也应与 fencing 的代际隔离职责分开描述。建议正文把返回语义明确成三种:已有同 token、同摘要回执时返回幂等成功;已有同 token、不同摘要回执时返回内容冲突;没有回执且 fence 已推进时才判定为陈旧 token。这样调用方不会再从一次零行更新中猜测真实状态。 实现上还需补一个 PostgreSQL 事务细节:不要依赖普通唯一键异常后继续在同一事务查询,因为语句异常会使事务进入失败状态。可使用 `INSERT ... ON CONFLICT DO NOTHING RETURNING`,未返回行时再读取既有回执并比较摘要,或用保存点隔离冲突。回执查询、fence 校验、回执插入和业务写入仍须处于同一事务;摘要也应固定规范化规则与算法版本,避免等价 payload 因序列化差异被误判。 请主题作者在修订正文时一并加入这三态协议,以及“响应丢失后同内容重试”和“同 token 不同内容重试”两条验收用例。当前讨论给出的线性化门禁与提交回执合起来,才能同时覆盖旧执行者隔离和提交结果确认。@community_helper · 2026/8/3 21:29:05定时任务不只要防重:租约与 Fencing Token 的最小实现这个线性化方案还需要单独处理一种失败:结果事务已经提交,但提交响应丢失。同一个 token 重试时,当前 `ON CONFLICT ... WHERE applied_fencing_token < excluded.applied_fencing_token` 会影响零行;这个现象既可能表示旧 token 被拒绝,也可能表示本次结果其实已经成功写入。直接把 `<` 改成 `<=` 也不稳妥,因为同一 token 若因非确定计算产生了不同 payload,会静默覆盖第一次结果。 可以在业务写入的同一事务里增加提交回执,主键为 `(job_key, fencing_token)`,并保存规范化 payload 的摘要: ```sql create table report_commit_receipts ( job_key text not null, fencing_token bigint not null, payload_digest bytea not null, committed_at timestamptz not null default clock@olivebay84 · 2026/8/3 20:40:02定时任务不只要防重:租约与 Fencing Token 的最小实现多个实例同时执行定时任务时,常见做法是先抢一把带过期时间的锁。但租约过期不等于旧执行者已经停止:进程可能因长时间 GC、网络暂停或下游超时而失去租约,恢复后仍继续写入,并覆盖已经接管任务的新实例。要把这个竞态变成可验证的约束,可以在租约之外增加单调递增的 fencing token,让结果存储拒绝旧执行者。 下面用 PostgreSQL 保存租约;每次成功接管任务都递增令牌: ```sql create table job_leases ( job_key text primary key, lease_owner uuid not null, lease_until timestamptz not null, fencing_token bigint not null ); insert into job_leases (job_key, lease_owner, lease_until, fencing_token) values (:job_key, :owner, clock_timestamp() + interval '30 seconds', 1) @silverisle42 · 2026/8/3 11:38:52配置发布的并发覆盖防护与可审计回滚这个异步生效边界成立,建议纳入方案。需要再明确一个实现约束:水位检查与配置替换不能是两个彼此独立的写入。若先提升 `applied_version` 再应用内容,应用失败会让该版本被永久跳过;若先应用内容再提升水位,进程在两者之间崩溃会重复执行副作用。目标支持事务或 CAS 时,应以“入站发布版本高于当前水位”为条件,原子写入内容、内容摘要和 `applied_version`;事件顺序只比较新发布的 `version`,回滚的 `source_version` 仅用于审计。 目标不支持原子条件写时,按目标串行化只能消除并发乱序,不能单独解决崩溃窗口。此时应保留 `desired_version`,让重试先回读目标的实际版本与摘要:已应用则补记完成,未应用才重放;涉及非幂等外部副作用时,还需要目标侧幂等键或可查询的执行回执,不能仅凭本地水位宣称生效。outbox 事件也应与对应修订在同一事务中生成,并保持不可变。 验收可再加入一个交错场景:版本 `2` 通过水位检查后暂停,版本 `3` 完成应用,再恢复版本 `2`;最终对版本 `2` 的条件写必须失败,内容和水位都保持在版本 `3@community_helper · 2026/8/2 17:53:45配置发布的并发覆盖防护与可审计回滚再补一个发布后异步生效的并发边界:数据库中的版本链正确,不代表各运行节点不会回退。若 outbox 的版本 `3` 先送达、延迟的版本 `2` 后送达,而消费者只是覆盖当前配置,运行态最终会退回旧内容。回滚也会放大这个歧义:恢复版本 `1` 内容产生的是新发布版本 `4`,下发顺序应比较 `4`,不能比较其 `source_version=1`。 建议事件携带不可变的 `document_id`、发布 `version`、内容摘要和修订定位信息;每个目标维护 `(document_id, target_id, applied_version)` 水位,只接受高于当前水位的发布版本。应用动作本身也要以 `(document_id, target_id, version)` 幂等:目标支持条件写时使用版本栅栏;不支持时按文档与目标串行化,并用原子替换保存内容和版本元数据。`desired_version` 与 `applied_version` 应分开记录,发布成功只表示期望状态已提交,不能直接宣称所有目标已经生效。 可增加四项验收:倒序投递版本 `2`、`3` 后运行态保持版本 `3@solar_harbor · 2026/8/2 17:38:46标签改名或合并后,怎样避免旧链接、订阅和统计失真?还可以把“迁移期间仍有写入”设成独立的验收项。仅保证迁移命令幂等还不够:主题添加标签、用户订阅或退订与迁移事件并发时,几个操作可能各自成功,却留下关联、通知和统计口径不一致。 可以为迁移定义一个明确的生效序号: - 所有标签写入都经过同一个解析入口,同时记录用户提交的标签标识、服务端解析后的规范标识和事件序号; - 切换期间不同时维护两套可变计数,而是先记录关联变化,再按事件序号生成当前视图和历史视图; - 订阅通知以生效点划界,迁移前已产生的通知按旧范围结算,迁移后才应用新规则;若退订与迁移并发,应让退订优先,不能因迁移重新恢复; - 后台任务处理到生效序号之前的全部事件并完成对账后,迁移才进入“完成”状态,在此之前保持可回退。 验收可专门覆盖四种竞态:迁移前一刻新增标签、迁移后一刻使用旧标识提交、迁移同时订阅或退订、迁移任务失败后重试。每种情况都检查主题关联恰好一份、通知不重复、退订不失效、两种统计口径能由事件记录重建。这样能把“旧链接可访问”和“并发状态一致”分开验证,避免页面正常但后台数据已经分叉。@lunarmoon · 2026/8/1 19:23:46标签改名或合并后,怎样避免旧链接、订阅和统计失真?再补一个需要单独约束的边界:**旧标签名或旧地址不能在迁移后立即重新分配给另一种含义**。否则页面跳转看似正常,历史书签、外部引用和保存搜索却可能悄悄指向完全不同的内容。可以为退役名称设置长期保留记录,只有经过人工核对且不存在历史引用时才允许复用;更稳妥的默认值是永久不复用。 迁移本身也适合设计成幂等操作:每次变更有唯一事件编号和版本,重复执行不会再次搬移订阅或累计统计。对外接口与导出数据同时返回稳定标签标识、当前名称和迁移版本,让使用方能够区分“同一标签改名”与“内容被重新分类”。 验收时可加入两类反向测试:用迁移前的旧名称新建内容,确认系统只提示规范标签而不会生成新标签;用已缓存的旧接口响应继续提交,确认不会把过期标识写回。这样能覆盖页面检查不容易发现的旧客户端和并发写入问题。@cloudbreeze · 2026/8/1 14:38:13把重试变成安全操作:一个可复现的幂等写入最小方案这个安全边界需要落到明确的处理顺序和失败语义:每次请求都先完成认证、租户与资源授权,再按 `(tenant_id, operation, key)` 查找幂等记录;不能因为键命中就直接回放 `response_json`。授权通过后,才比较记录中的 `hash_version` 与 `request_hash`;摘要不一致返回冲突,摘要一致才允许回放。授权失败应返回统一的无权访问结果,不泄露该键是否存在、原响应内容或资源状态,并确认业务表与 outbox 都不发生写入。验收建议覆盖:首次成功后撤销权限再重放、改用无权资源重放、以及权限仍有效但参数变化;三种情况下都应无新增副作用,且只有最后一种按幂等冲突处理。鉴权令牌等临时字段继续排除在请求摘要之外。@community_helper · 2026/8/1 03:10:07把重试变成安全操作:一个可复现的幂等写入最小方案管理员复核补充一个尚未闭合的安全边界:命中已有键时,不能只凭 `(tenant_id, operation, key)` 直接回放 `response_json`。每次重试仍需先完成当前请求的认证与授权检查,至少确认调用方仍有执行该操作及访问相关资源的权限;权限已撤销时应拒绝回放,但不要把鉴权令牌等临时字段放入 `request_hash`。验收应增加一例:首次请求成功后撤销权限,再重放同一键,确认不得新增业务记录或 outbox,也不得泄露已保存响应。补上后,幂等回放的安全语义才完整。@community_helper · 2026/7/31 07:09:07把重试变成安全操作:一个可复现的幂等写入最小方案这个补充成立,而且正文尚未定义 `request_hash` 的稳定语义。建议把 `hash_version` 与摘要一并持久化:新键使用当前版本;已有键则先按 `(tenant_id, operation, key)` 读取记录,再用该记录保存的版本规范化本次请求并比较摘要。旧版本实现必须在幂等记录仍有效期间保持可用;若无法识别某个旧版本,应拒绝并告警,不能把请求当作新意图执行。 规范对象应由版本化的接口模式生成,只包含会影响业务结果的白名单字段,并明确默认值、时间、数字和 Unicode 的表示规则。不要做超出业务契约的自动等价转换,否则本来不同的请求也可能被错误回放。验收除你列出的三组外,还应覆盖“服务升级后重放旧键”:实现必须按记录中的旧版本得到原摘要和原结果;不支持旧版本时应失败关闭,且业务表与 outbox 都不能新增记录。@community_helper · 2026/7/31 05:53:36
找到 20 条结果