长时间运行的事务在 BizTalk 业务流程编排中是非常重要且常用的构造。 它们为你提供了基于自定义作用域的补偿、异常处理以及嵌套事务的功能,这一切让你在设计可靠的事务体系结构方面具有极大的灵活性。
如果事务可能需要长期运行,并且您不需要完整的 ACID 属性(即不需要保证与其他事务之间的数据隔离),则可以使用长期运行事务。 长时间运行的事务可能长时间处于非活动状态,这通常是由于等待外部消息到达。
长时间运行的事务具有一致性和持久性,但不具有原子性和隔离性。 长时间运行的事务中的数据未锁定;其他进程或应用程序可以修改它。 不保留状态更新的隔离属性,因为长时间持有锁是不切实际的。
长时间运行的事务的承诺不同于原子事务的承诺。 没有关于结果的分布式协调的隐式假设(长时间运行的事务仅存在于单个业务流程实例中)。 相反,长时间运行的事务在其中的最后一个语句完成时被视为已提交。 如果事务中止,则不会“自动”回滚状态。 可以通过异常和补偿处理程序以编程方式实现此目的。
范围可以通过声明变量、消息和 .NET 组件来定义自己的状态。 长时间执行的事务可以访问其自身作用域的状态信息、任何包含它的作用域,以及在编排中全局定义的任何状态信息。 它无法访问不包含它的任何作用域的状态信息。
嵌套
长时间运行的事务可以包含原子事务或其他长时间运行的事务。 它们可以嵌套到任意深度。 例如,你的事务可能包含另外两个长时间运行的事务,其中每一个可能包含原子事务。
当整体事务中的一个或多个组件需要具备原子性,而整体事务需要长时间运行时,嵌套尤其有用。 请考虑接收和履行采购订单的示例。 采购订单可以随时到达,完成订单的各个步骤可能需要时间才能完成,但你仍希望将整个过程视为交易。 在这种情况下,整体交易显然需要长时间运行,但单个步骤(如确认付款)可能需要具备原子性。
注释
不能在非事务性的作用域或业务流程中嵌套事务范围。 非事务性的封闭作用域或编排将不会管理状态,因为它必须能够正确处理其内部任何作用域的状态管理。
注释
同步的事务不能包含任何其他事务或同步范围。
薪酬
长时间运行的事务可以指定一个补偿块,在提交后调用以补偿事务的活动。 它可能只是在可行的情况下撤消事务,或者执行其他一些函数(例如通知),以帮助以某种方式缓解事务的影响。 如果不添加自己的补偿代码,运行时引擎将默认按照相反的顺序调用内部事务(无论是长时间运行还是原子事务)的补偿块,从最后提交的事务开始,最后以第一个提交的事务结束。
注释
只能对已成功提交的事务执行补偿。
容错
事务支持从内部故障(例如计算机故障和软件故障)以及外部故障(例如取消消息)中恢复的容错能力。 在长时间运行的事务中,当事务发生故障时,部分更新不会像在 ACID 事务中那样自动回滚。
当发生错误时,会调用长时间运行事务的异常代码块。 异常代码块包含一组错误处理程序,用于处理在执行事务期间可能出现的任何错误。 你可以依赖消息、变量和对象在处理故障时的最后已知状态。
您通常希望异常处理程序在发生异常时评估编排的状态,根据该状态执行所有必要的操作,并实现对任何嵌套事务的补偿。
发生错误时,长时间运行的事务的执行将中断。 发生错误后无法恢复。