设计业务层
应用程序的核心是它提供的业务功能。一个应用程序执行一个业务过程,这个过程有一个或多个任务组成。在最简单的情况下,每个任务被封装在一个DotNET组件的方法里,被同步或者异步调用。更复杂的业务过程,需要多步和长期运行的事务处理,应用程序需要有一些方法编排业务任务和存储状态,直到过程被处理完成。在这些场景下,可以使用BizTalk Server Orchestration来定义业务流程的工作流。然后,实现工作流的BizTalk Server Orchestration进度表可以使用BizTalk Server消息功能,或者DotNET业务组件来执行它需要的每个任务。
在业务层中,可以设计逻辑被表现组件直接使用,或者作为一个服务封装,通过一个服务接口调用,这个服务接口调和与服务调用者的异步会话,且调用BizTalk Server的工作流或者业务组件。业务逻辑的核心有时也被作为“域”逻辑引用。业务组件也可以成为外部服务请求,在这个情况下,可能需要实现服务代理来管理会话,这个会话指的是你使用的每个服务执行的特定业务任务。
下面的图2.6显示一个应用程序的业务层。
图2.6 业务组件层
业务组件和工作流
当实现业务功能时,必须决定是否需要编排业务过程或者一套的业务组件是否充足。
要使用业务工作流(用BizTalk Orchestration实现),来做:
l 管理一个过程,这个过程包括多个步骤的处理和长期运行的事务处理。
l 暴露接口,这个接口实现业务过程,使应用程序可以参与一个会话,或者参与和其它服务的契约。
l 为BizTalk Server有用的多种技术,发挥适配器和连接器更广泛的优势。
在下面条件下,使用唯一的业务组件实现业务过程:
l 在业务活动的背后,不需要维护会话的状态,业务组件功能应该作为单个原子事务被实现。
l 为了多个业务过程的重用,需要封装功能和逻辑。
l 需要被实现的业务逻辑是精密的计算,或者需要对数据结构和API的精细控制。
l 在数据和逻辑流上需要有良好的控制。
在零售应用程序里,提交一个订单的过程包括多个步骤(审核信用卡,处理支付,安排交货,等等),这些步骤需要在指定的序列中被执行。为这种业务过程设计最适合的方法是来创建业务组件,这些业务组件封装在过程中的每个独立的步骤,并安排使用工作流编排这些组件。
设计业务组件
业务组件可以作为原子事务的根。他们实现多种模式的业务规则,接受和返回简单或者复杂的数据结构。业务组件暴露功能在一个方法中隐藏数据存储和需要执行工作的服务,且会被妥当安排在更深层次和事务性上的一致性方法中。
业务逻辑一般会进化和增长,提供更高层次的操作和封装原已存在的逻辑。在许多情况下,需要妥善安排原来存在的业务功能,目的是执行已经需要过的业务逻辑。当妥善安排逻辑时,必须特别注意什么时候事务是相关的。
如果在一个原子事务的语境中,一个业务过程被另一个业务过程调用,所有的已调用的业务必须确保它们的操作参加到已存在的事务中,以便操作在调用业务逻辑失败时,可以被回滚。如果失败,不担心造成数据的不一致,可以放心地重试任何原子性的操作。可以把一个事务边界作为一个可重试边界来考虑。横穿运行Windows的服务的事务用DTC(Distributed Transaction Coordinator)管理,这个通过DotNET Enterprise Services(COM+)应用。在异构环境中管理分布式事务,可以使用COM事务集成(COMTI)和宿主集成服务器2000(Host Integration Server 2000)。有关COMTI和宿主集成服务器2000的更多信息,见
http://www.microsoft.com/hiserver。
如果不能实现原子事务,需要提供补偿方法和处理。注意,补偿行为不是必需回滚所有应用程序数据到以前的状态,仅需要恢复业务数据到一致的状态。例如,如果你是一个供应商,你可以暴露B2B购物接口给合作伙伴。取消一个订单的补充行为的处理,可以包括冲入一个订单取消费。对于更长运行的事务和处理讲,补偿行为在不断的工作流状态中是不同的,所以,在过程中,需要使用合适的步骤设计这些。
有关处理事务和隔离层次问题的更多信息,见MSDN上的“Transactions” in “.NET Data Access Architecture Guide” (http://msdn.microsoft.com/library/en-us/dnbda/html/daag.asp)。
下面列举了一些为设计业务组件的建议总结:
l 仅可能多的依赖基于消息的通讯。
l 确保通过服务接口暴露的过程是等幂的(idempotent),这就意味着,如果相似的消息被接受两次,应用程序或者服务不会影响一致的状态。
l 小心地选择事务边界,以便使重试和组合成为可能。这个应用到原子和长期运行的事务中。也可以考虑为基于消息的系统使用重试,特别当把应用程序功能作为一个服务暴露时。
l 业务组件尽可能地能够运行在任意一个服务用户上下文环境中---不必要拟定一个特定的应用程序用户。这个允许调用它们不需要带有转送或者委托用户身份的机制。
l 选择和保持一个一致性的数据格式(如,XML,DataSet等等)来用于输入参数和返回值。
l 设置合适地事务隔离层。有关处理事务和隔离层问题的更多信息,见MSND上的“Transactions” in “.NET Data Access Architecture Guide” (http://msdn.microsoft.com/library/en-us/dnbda/html/daag.asp)。