Skip to content

fix(db-server,sdk): 新脚本实例启动时回收旧实例遗留的事务会话 - #161

Merged
Tanya7z merged 1 commit into
mainfrom
fix/tx-reap-on-start
Oct 26, 2026
Merged

Tanya7z merged 1 commit into
mainfrom
fix/tx-reap-on-start

Conversation

@Tanya7z

@Tanya7z Tanya7z commented Oct 26, 2026

Copy link
Copy Markdown
Member

问题

/reload 时旧脚本实例刚开启的交互式事务(tx/begin 已在 db-server 建会话,但客户端还没拿到 txId)来不及提交或回滚,会占住 db-server 的全局事务槽直到 15 秒空闲超时。新脚本实例里任一模块 init 的读写在这期间排队 2 秒后返回 transaction_busy(「事务繁忙」),例如 land 初始化失败。

线上日志实例:economy 会话 19:31:09 begin、19:31:10 reload;online-time 会话 19:51:13 begin、19:51:14 reload,二者都没有任何 step,只靠空闲超时回收。

修复(reap on start)

  • db-server:TxRunner.abortModuleSessions(moduleId) + POST /api/sfmc/db/tx/reap(body {} → { ok, aborted })。只中止鉴权身份所属模块的会话,模块不能回收别人的会话。
  • sdk:DbClient.reapOrphanSessions()(不暴露在 legacy db 门面上);宿主 runStartup 在 ModuleRegistry.bootAll() 之前逐模块调用一次。无 token 跳过;失败只记日志、不阻断启动(兼容未升级的 db-server)。
  • changeset:@sfmc-bds/db-server / @sfmc-bds/sdk patch。

已知边界

旧实例若有 tx/begin 仍在事务槽队列里等待,可能在 reap 之后才建出新的孤儿会话;这种情况仍由原有 15 秒空闲超时兜底。

验证

  • packages/db-server: tsc7 --noEmit 通过;node --test 28/28(新增 test/tx-reap.test.ts:遗留会话阻塞其他模块 → 回收其他模块返回 0 仍阻塞 → 回收本模块返回 1 后立即可开事务)
  • modules/sdk/@sfmc-sdk: tsc7 --noEmit -p tsconfig.types.json 通过;qq-link 测试 8/8

/reload 时旧脚本实例刚开启的交互式事务来不及提交或回滚,会占住 db-server
全局事务槽直到 15 秒空闲超时,新实例模块 init 读写返回「事务繁忙」。

- db-server: TxRunner.abortModuleSessions + POST /api/sfmc/db/tx/reap,
  只中止鉴权身份所属模块的会话
- sdk: DbClient.reapOrphanSessions;宿主在 bootAll 前逐模块回收,失败不阻断启动
- 新增 db-server 测试 tx-reap.test.ts

Co-authored-by: Cursor <cursoragent@cursor.com>
@Tanya7z
Tanya7z merged commit a25104f into main Oct 26, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant