在OData服务层上完成事务有哪些策略?

时间:2013-07-11 15:17:56

标签: web-services rest transactions asp.net-web-api odata

考虑以下示例:

OData服务层公开Order和OrderLine资源。消费者检索订单及其相关的OrderLines。消费者编辑订单,编辑1 OrderLine,删除1 OrderLine并创建1 OrderLine。消费者如何保存所有这些变化,确保更改全部或全部?

根据我对OData的理解,这将作为多个服务电话发送:

  

PUT / api / Order / 9999
  PUT / api / OrderLine / 1001
  DELETE / api / OrderLine / 1002
  POST / api / OrderLine / 1002

每个呼叫都是无状态且独立的,服务器无法确定何时开始和结束事务。

<小时/> 我考虑了各种解决方案,但我不确定它们是否有效:

解决方案1)让Order资源包含OrderLine信息。使用此解决方案,将使用“PUT / api / Order / 9999”进行单个服务调用,其中包含所有OrderLine更改。此策略似乎很好,因为它从服务器上的事务详细信息中抽象出消费者。但是,在使用Breeze和WCF数据服务客户端进行PUTting时,我找不到将OrderLine集合包含到Order实体中的方法。此外,我不确定如何在订单中传达删除OrderLine。 OData规范中有什么可以实现这一目标吗?我发现可以在section 10.3.2.2 of the spec中POST相关实体。在PUTting实体时,我没有发现任何类似的创建/更新/删除相关实体。

解决方案2)使用OData的$ batch操作会将4个服务调用作为一个发送。我不确定$ batch功能的用途是用于性能还是用于将相关服务调用分组到事务中。使用$ batch进行事务处理,消费者有责任确定在同一批次中发送哪些服务调用。这是一个适当的关注点分离?在服务器端,批处理程序可能会变得复杂。如果在Order和OrderLine之间需要进行任何验证,批处理程序将需要重新组合这些对象并在尝试数据库事务之前验证它们。

解决方案3)公开开始和结束交易服务电话。同样,这将向消费者公开实施细节。我认为其含义与解决方案2非常相似。

该解决方案必须适用于.NET 4.0,并且服务调用必须适用于.NET和javascript客户端。可伸缩性不是问题。我正在使用“Web API OData”,它永远不会支持.NET 4.0中的$ batch功能,但转换为“WCF数据服务”是可能的。我选择了OData来检索它的功能,但如果没有OData,CUD操作的事务工作会更好,我会接受建议。一种可能性是继续将OData用于我的应用程序的高级搜索屏幕,但是为CUD使用常规REST服务。

1 个答案:

答案 0 :(得分:2)

如果您正在使用WCF数据服务,则四个操作将一起发送,因此批处理将为您工作。 WCF数据服务的EF内置实现将在调用SaveChanges之前将EF操作上下文中的更改放在一起,如果SaveChanges调用失败,则会全部或全部无效,模拟事务的行为。