Transactions Akka流和事务边界

Transactions Akka流和事务边界,transactions,akka,akka-stream,reactive-streams,Transactions,Akka,Akka Stream,Reactive Streams,我仍然掌握Akka流的概念,并试图理解当我们有一个需要以原子方式处理的项目集合时,如何将它们映射到场景中。假设我们有一个由多个项目组成的采购订单,我们需要对每个项目应用一些处理,然后将它们合并回单个值。该工作流是否应成为其自己的独立流(或子流),一旦采购订单得到完全处理,该流将关闭?即,每个采购订单启动一个新流程?或者我的采购订单源源不断?但如果是这样的话,我会不会有一个混合不同订单的采购订单的问题 换句话说,我试图实现的是对不同工作流的处理隔离,并想知道Akka streams是否能很好地匹配

我仍然掌握Akka流的概念,并试图理解当我们有一个需要以原子方式处理的项目集合时,如何将它们映射到场景中。假设我们有一个由多个项目组成的采购订单,我们需要对每个项目应用一些处理,然后将它们合并回单个值。该工作流是否应成为其自己的独立流(或子流),一旦采购订单得到完全处理,该流将关闭?即,每个采购订单启动一个新流程?或者我的采购订单源源不断?但如果是这样的话,我会不会有一个混合不同订单的采购订单的问题


换句话说,我试图实现的是对不同工作流的处理隔离,并想知道Akka streams是否能很好地匹配它。

直接回答您的问题:可以创建一个流,该流将“对每个项目应用一些处理,然后将它们合并回单个值”

使用一些示例代码开发您的示例:

case class Item(itemId : String)

case class PurchaseOrder(orderId : String, items : Seq[Item])

val purchaseOrder : PurschaseOrder = ???
如果我们想用流处理项目,我们可以,尽管问题中减少的确切性质不明确,因此我不会定义如何实现折叠:

type ProcessOutput = ???

def processItem(item : Item) : ProcessOutput = ???

val combinedResult : Future[CombinedResult] = 
  Source.fromIterator( purchaseOrder.items.toIterator )
        .via(Flow[Item] map processItem)
        .to(Sink.fold[ProcessOutput](???)(???) )
        .run()
间接回答你的问题,

首先考虑期货

当需要背压时,Akka流非常有用。当您连接到外部数据源时,背压很常见,因为bp允许您的应用程序确定数据流传输到您的速度,因为您负责不断发出更多数据需求的信号

在您在问题中提出的情况下,无需广播此类通信所需的需求。您已经有一个项目集合,因此没有人向您发送需求

相反,我认为期货是处理你所描述的情况的最佳方式:

def futProcess(item : Item)(implicit ec : ExecutionContext) = 
  Future { processItem(item) } 

// same output type as the stream run 
val combinedResults : Future[CombinedResult] = 
  Future.sequence{ purchaseOrder.items map futProcess }
        .map{ _ fold[ProcessOutput](???)(???) }

拥有一个完整的ActorSystem,您将获得更好的性能、更少的复杂性,并且无论怎样,都会得到与流完全相同的结果

谢谢你的详细回答。我也明白,在某些情况下,正如您所指出的,流可能是次优的。但总体而言,我看到了溪流的巨大潜力,我想看看它们。