使用 WCF 服务模型在 SAP 中接收入站 tRFC 调用
可以将适用于 mySAP Business Suite 的 Microsoft BizTalk 适配器用作事务性 RFC (tRFC) 服务器来接收来自 SAP 的入站 tRFC 调用。 对于入站 TRFC,SAP 适配器支持在同一 SAP 逻辑工作单元中 (LUW) 中的多个 tRFC。
本主题中的各节提供有关如何在 WCF 服务模型中将适配器用作 tRFC 服务器的信息。
有关将 SAP 适配器用作 tRFC 服务器的详细信息,请参阅以下主题:
有关 SAP 适配器上对 tRFC 的支持的概述,请参阅 SAP 中 tRFC 的操作。 在继续之前,应先阅读本主题。
有关 tRFC 服务器操作的消息架构的详细信息,请参阅 SAP 中 tRFC 的操作。
tRFC 的 WCF 服务协定
使用添加适配器服务引用 Visual Studio 插件或 ServiceModel 元数据实用工具 (svcutil.exe) 为要从 SAP 系统接收的 tRFC 生成 WCF 服务协定。 为入站 tRFC 生成的协定类似于为入站 RFC 生成的协定,不同之处在于:
tRFC 操作显示在 TRFC 节点下。
为传入 tRFC 生成的 WCF 服务协定 (接口) 名为“Trfc”。 将服务终结点添加到服务主机时,必须指定此接口。 这也是 WCF 服务必须实现的接口。
public interface Trfc { // CODEGEN: Generating message contract since the wrapper namespace (http://Microsoft.LobServices.Sap/2007/03/Trfc/) of message Z_RFC_MKD_ADDRequest does not match the default value (http://Microsoft.LobServices.Sap/2007/03/) [System.ServiceModel.OperationContractAttribute(Action="http://Microsoft.LobServices.Sap/2007/03/Trfc/Z_RFC_MKD_ADD", ReplyAction="http://Microsoft.LobServices.Sap/2007/03/Trfc/Z_RFC_MKD_ADD/response")] Z_RFC_MKD_ADDResponse Z_RFC_MKD_ADD(Z_RFC_MKD_ADDRequest request); }
TRFC 操作的请求消息协定具有 GUID 参数。 这是映射到 tRFC 的 SAP TID 的 GUID。 在 tRFC 服务器操作中,适配器管理 SAP 系统提交、回滚和确认 TID 的所有调用,因此你没有理由显式使用此 GUID。 但是,可以使用它通过调用 SapAdapterUtilities.ConvertGuidToTid 从 SAP 适配器检索 SAP TID。 这有助于排查 SAP 系统上的问题。
[System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] [System.ServiceModel.MessageContractAttribute(WrapperName="Z_RFC_MKD_ADD", WrapperNamespace="http://Microsoft.LobServices.Sap/2007/03/Trfc/", IsWrapped=true)] public partial class Z_RFC_MKD_ADDRequest { ... public Z_RFC_MKD_ADDRequest(string DEST, System.Nullable<int> X, System.Nullable<int> Y, System.Guid TransactionalRfcOperationIdentifier) { this.DEST = DEST; this.X = X; this.Y = Y; this.TransactionalRfcOperationIdentifier = TransactionalRfcOperationIdentifier; } }
如何实现使适配器充当 tRFC 服务器?
若要使适配器充当 tRFC 服务器,必须将 TidDatabaseConnectionString 绑定属性设置为 TID 数据库的连接字符串。 应在打开服务主机之前执行此操作。 这是适配器存储每个 tRFC 的 SAP 事务 ID (TID) 的数据库。 有关此绑定属性的详细信息,请参阅 了解 mySAP Business Suite 绑定属性的 BizTalk 适配器。
如何实现入站 TRFC 的事务中登记?
SAP 逻辑工作单元 (LUW) 可以包含多个 tRFC。 在 SAP 系统上,LUW 由唯一事务 ID (TID) 标识。 适配器为 SAP 系统在调用适配器上的 tRFC 调用时使用的每个 TID 创建一个可提交的事务。 当 SAP 系统调用适配器上的 tRFC 时;适配器将与 SAP TID 关联的事务流向服务。 可以从操作方法内部以环境事务的形式访问此事务。 通过在此环境事务中登记,在操作中执行的操作可以参与 SAP LUW。
若要在操作方法中登记环境事务,必须:
使用 OperationBehavior 属性的 TransactionScopeRequired 属性批注操作方法。 这会告知 WCF 你想要从操作内部访问环境事务。
通过使用 OperationBehavior 属性的 TransactionAutoComplete 属性批注操作方法,或者在操作方法内显式使用 TransactionScope 来创建事务范围。
以下示例演示了一个实现两个操作的服务。 这两种操作方法都使用 TransactionScopeRequired 属性进行批注,以访问环境事务。
Z_TRFC_EXAMPLE1 使用 TransactionScope 对象在事务中显式登记。
Z_TRFC_EXAMPLE2 使用 TransactionAutoComplete 属性进行批注,以在事务中登记
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, UseSynchronizationContext = false)]
class Z_Example_ServiceContractClass : Trfc
{
// This operation method explicitly creates a TransactionScope to enlist in the ambient transaction
// You must explictly call ts.Complete to complete the transaction before you return from the operation
// Otherwise the transaction is aborted.
// You can throw an exception or return without calling ts.complete to abort the transacation
[OperationBehavior(TransactionScopeRequired = true)]
public Z_TRFC_EXAMPLE1Response Z_TRFC_EXAMPLE1(Z_TRFC_EXAMPLE1Request request)
{
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
{
// Process tRFC
...
Z_TRFC_EXAMPLE1Response response = new Z_TRFC_EXAMPLE1Response();
response.TransactionalRfcOperationIdentifier = request.TransactionalRfcOperationIdentifier;
return response;
//since there is no ts.Complete(), this is equivalent to a rollback.
}
}
// This operation method sets the TransactionAutoComplete property of the OperationBehavior attribute
// to enlist in the transaction. There is no need to explictly create a TransactionScope in the code.
// If the method returns with no unhandled exceptions, the transaction completes; otherwise it aborts
// You can throw an exception to abort the transaction.
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public Z_TRFC_EXAMPLE2Response Z_TRFC_EXAMPLE2(Z_TRFC_EXAMPLE2Request request)
{
// Process tRFC
...
Z_TRFC_EXAMPLE2Response response = new Z_TRFC_EXAMPLE2Response();
response.TransactionalRfcOperationIdentifier = request.TransactionalRfcOperationIdentifier;
return response;
//if there is no unhandled exception, the transaction completes when the operation returns.
}
}