事务语义对照表

概览

本页聚焦 Juice 当前事务 API 的**行为语义**,帮助你在 service 设计时快速选型。

术语说明:

  • 手动事务engine.Tx() / engine.ContextTx(...) + Begin/Commit/Rollback

  • 函数式事务juice.Transaction(...) / juice.NestedTransaction(...)

  • 当前事务上下文ctx 里 manager 已是 TxManager

语义对照表

API

启动条件

成功时行为

失败时行为

典型场景

engine.Tx() + Begin

需要手动调用 Begin

显式 Commit 后提交

显式 Rollback 或返回错误后回滚

底层库/基础设施层,细粒度控制

engine.ContextTx(ctx, opts)

与上面一致,但可传 sql.TxOptions

与上面一致

与上面一致

指定隔离级别、只读事务

juice.Transaction(ctx, handler, opts...)

ctx 必须携带 *juice.Engine

handler 返回 nil 则提交

handler 返回非 nil 则回滚

service 层统一事务边界

juice.NestedTransaction(ctx, handler, opts...)

若当前已在事务中则复用;否则新开事务

复用时由外层统一提交;新开时按 Transaction 规则

复用时错误向外层冒泡;新开时失败回滚

组合 service、避免重复开启事务

行为细节

1) ``Transaction`` 的上下文要求

juice.Transaction 会从 ctx 取 manager,并要求它是 *juice.Engine。如果不是,会返回错误。

常见错误:

  • ctx 没有通过 juice.ContextWithManager 注入 manager。

  • 把一个已处于事务中的 ctx 直接再次传给 Transaction``(此时 manager 往往不是 ``*juice.Engine)。

推荐:

  • 外层入口使用 Transaction

  • 内层复用使用 NestedTransaction

2) ``NestedTransaction`` 不是 savepoint

NestedTransaction 的语义是“有事务就加入,没有就创建”,不是数据库 SAVEPOINT

这意味着:

  • 复用外层事务时,不会产生独立的“内层提交点”。

  • 内层失败会影响外层是否提交(通常应向上返回错误)。

3) 特殊错误 ``tx.ErrCommitOnSpecific``

handler 返回 tx.ErrCommitOnSpecific 时,事务仍会尝试提交,并将该错误与提交错误(如果存在)一起返回。

这用于“需要显式标记某类提交路径”的特殊场景;一般业务代码不建议常态化使用。

实战选择建议

  • 需要完全可控的生命周期:选**手动事务**。

  • 以业务函数为边界:优先**函数式事务**。

  • service A 调 service B,且都可能独立调用:外层 Transaction + 内层 NestedTransaction

  • 如果你需要 savepoint 级别的细粒度语义:建议在业务侧按数据库能力自行封装。