【问题标题】:How can you effectively use web services in an enterprise environment if you can't use transactions?如果不能使用事务,如何在企业环境中有效地使用 Web 服务?
【发布时间】:2012-02-14 00:11:28
【问题描述】:

我工作的地方是试图建立一些基本规则,而我们现在的争论是本地库与 Web 服务的代码重用。 Web 服务似乎是大多数公司的热门选择,这也是这里的大多数开发人员所倾向于的。

我只是不明白如何有效地使用 Web 服务进行任何严肃的工作。如果我不能使用事务,如何安全地执行多个服务调用?

假设我有一个 cron 作业,它从我们的数据库中抓取满足特定条件的客户,这些客户需要得到通知。他们会收到一份传真、一封电子邮件,并创建一张票以在内部跟踪问题。也就是说,for 循环中的每个客户都会发生 3 次不同的服务调用。

如果其中任何地方发生错误,例如,可能会向客户发送传真和电子邮件,但未创建票证。或者更糟糕的是,这个 cron 作业可能包含一个错误,导致它每次都在同一点失败,并且它反复向同一个客户发送电子邮件。如果库都是本地的,那么一切都可以包装在事务中,而这一切都不会发生。但是我们在这个例子中使用了网络服务。

请注意,电子邮件和传真方法实际上将数据插入到电子邮件队列和传真队列中,而这又由 cron 作业处理。因此对“发送电子邮件”和“发送传真”服务方法的调用可以安全回滚。

一种选择是将整个代码块放在 Web 服务本身中,这样 Web 服务本身就会在事务中调用电子邮件、传真和票证创建方法。但是我们正在创建一个仅用于事务的 Web 服务方法;除了这个 cron 脚本之外,我们没有任何正当理由需要从任何地方调用此方法。

您一般会如何处理这种方法?

【问题讨论】:

    标签: web-services service soa


    【解决方案1】:

    我会通过构建 SAGA 来处理它,SAGA 是对具有内部状态、响应外部事件并与外部系统交互的长期运行业务流程的抽象。

    我会这样做是因为您的问题陈述不完整:当您因为服务器关闭而无法发送电子邮件时会发生什么?如果传真系统不工作,而其他两个不工作怎么办?

    当你不能调用一个时,你应该重试吗?多长时间?如果您无法在四个小时内提出罚单,会发生什么情况,您应该升级给某人吗?这是否应该得到响应,所以需要跟踪票证状态并在一段时间后升级?如果您无法执行任何通知操作,是否应该在某个时间向原始提交者发送电子邮件?

    当你不能只拥有一个事务时,使用 saga 是一种模型,因为它可能会在操作完成之前跨越数小时的实时时间 - 并且持有这么长时间的数据库锁,哎呀。

    迁移到 SOA 意味着摆脱您的一些旧假设。其中之一是您应该编写方法并调用它们,以便在更高级别封装系统行为并将其公开为服务。

    如果您尝试构建一个类似于本地图书馆的 Web 服务,那么您的生活将会一团糟。从您希望拥有数据的服务以及拥有与该数据相关的行为的服务的角度来处理此问题,并将详细信息封装在其中。

    (顺便说一句,我怀疑从 cron 发送这些东西实际上是一个更大的业务流程的一部分,对,cron 在其中做一些事情,并因此发送通知。您的服务可能很想公开它而是将整个序列作为一个传奇。)

    无论如何,重点是:您不会因为需要事务而将事物封装在服务中,也不会为了使它们成为原子而将事物放入事务中。这些是单独的问题,应该单独处理。

    PS:如果您使用交易,如果发送电子邮件但未创建票证,您不会发送两次电子邮件吗?无论如何,您实际上需要一组更细粒度的更新。

    【讨论】:

    • 我两次更新了关于电子邮件和传真的帖子。电子邮件和传真方法实际上将数据插入到电子邮件和传真队列中,由它们自己的 cron 作业处理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-23
    • 2014-05-02
    • 1970-01-01
    • 2015-04-09
    • 2011-06-02
    • 2019-05-14
    相关资源
    最近更新 更多