You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从CordaService调用serviceHub.startFlow与Flow调用子流的差异及报错咨询

Corda流调用的两种方式差异及错误排查

核心差异点

线程与执行上下文

  • Subflow调用:和父流共享同一个Flow协程执行上下文,包括事务上下文、Corda专用的协程调度器,挂起逻辑完全融入父流的协程生命周期,无需额外处理上下文传递。
  • CordaService调用:通过serviceHub.startFlow启动的是独立Flow实例,运行在单独的协程中;CordaService本身是单例服务,运行在普通线程池,不会自动为启动的Flow注入Flow专属的事务上下文。

挂起机制约束

  • Subflow:父流的@Suspendable注解会为整个调用链提供合法的协程上下文,即使子流的部分方法未标注注解,也可能被父流的上下文兜底,不会触发上下文缺失错误。
  • CordaService启动的流:必须严格遵守Corda的协程规则,所有挂起方法(包括流入口的call()方法)都必须标注@Suspendable,否则Corda无法为其创建事务上下文,直接抛出异常。

事务上下文传递

  • Subflow:自动继承父流的事务上下文,流内的操作(比如创建、签署事务)能直接复用父流的上下文信息。
  • CordaService:启动的流没有现成的事务上下文可继承,必须依赖@Suspendable注解让Corda的协程框架初始化并维护事务上下文。

你的错误原因及解决办法

错误根源

你调用的目标流存在未标注@Suspendable的挂起方法——要么是流的call()方法没加注解,要么是流内部调用的自定义挂起方法(比如封装了send()/receive()/subFlow()的方法)遗漏了注解。Subflow调用时因为父流的上下文兜底,没触发检查,但CordaService启动独立流时,Corda会严格校验协程上下文,因此抛出Transaction context is missing异常。

解决方案

  1. 检查目标流的call()方法,确保顶部标注@Suspendable注解:
    @Suspendable
    override fun call(): YourReturnType {
        // 流逻辑
    }
    
  2. 遍历流内所有自定义方法,只要方法内部调用了Corda的挂起API(比如subFlow()、send()、serviceHub.vault.queryBy()),就必须给该方法加上@Suspendable注解。
  3. 若在CordaService中启动流时需要指定协程上下文,可绑定Corda的应用协程上下文:
    val appCoroutineContext = serviceHub.getAppContext().coroutineContext
    serviceHub.startFlow(::YourTargetFlow, params).execute(appCoroutineContext)
    
    不过最核心的还是补全所有必要的@Suspendable注解。

内容的提问来源于stack exchange,提问作者Benjamin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 01:15:31