https://msdn.microsoft.com/zh-cn/biztalk/ms751493

本示例演示如何使用消息队列 (MSMQ) 执行已经过事务处理的排队通信。

注意

本主题的末尾介绍了此示例的设置过程和生成说明。

在排队通信中,客户端使用队列与服务进行通信。 更确切地说,客户端向队列发送消息。 服务从队列接收消息。 因此,不必同时运行服务和客户端便可使用队列进行通信。

当事务用于发送和接收消息时,实际上有两个单独的事务。 当客户端在事务范围内发送消息时,事务相对于客户端和客户端队列管理器来说是本地事务。 当服务在事务范围内接收消息时,事务相对于服务和接收队列管理器来说是本地事务。 请务必牢记,客户端和服务不会参与同一个事务;实际上,它们在对队列执行操作(如发送和接收)时使用的是不同的事务。

在本示例中,客户端在事务范围内向服务发送一批消息。 然后,服务在服务定义的事务范围内接收发送到队列的消息。

服务协定为 IOrderProcessor,如下面的示例代码所示。 此接口定义了适合与队列一起使用的单向服务。

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
[OperationContract(IsOneWay = true)]
void SubmitPurchaseOrder(PurchaseOrder po);
}

服务行为通过将 TransactionScopeRequired 设置为 true 来定义操作行为。 这可确保此方法所访问的任何资源管理器都使用相同的事务范围从队列中检索消息。 它还确保在方法引发异常的情况下,将消息返回到队列。 如果未设置操作行为,队列通道会创建一个从队列中读取消息的事务,并在调度前自动提交该事务,这样当操作失败时,消息将丢失。 对于服务操作而言,最常见的方案是在用于从队列中读取消息的事务中进行登记,如下面的代码中所示。


// This service class that implements the service contract.
// This added code writes output to the console window.
public class OrderProcessorService : IOrderProcessor
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SubmitPurchaseOrder(PurchaseOrder po)
{
Orders.Add(po);
Console.WriteLine("Processing {0} ", po);
}

}

服务是自承载服务。 使用 MSMQ 传输时,必须提前创建所使用的队列。 可以手动或通过代码完成此操作。 在此示例中,该服务包含代码,以检查队列是否存在并在不存在时创建队列。 从配置文件中读取队列名称。 ServiceModel 元数据实用工具 (Svcutil.exe) 使用该基址来生成服务的代理。

// Host the service within this EXE console application.
public static void Main()
{
// Get the MSMQ queue name from appSettings in configuration.
string queueName = ConfigurationManager.AppSettings["queueName"]; // Create the transacted MSMQ queue if necessary.
if (!MessageQueue.Exists(queueName))
MessageQueue.Create(queueName, true); // Create a ServiceHost for the OrderProcessorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(OrderProcessorService)))
{
// Open the ServiceHost to create listeners and start listening for messages.
serviceHost.Open(); // The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine(); // Close the ServiceHost to shut down the service.
serviceHost.Close();
}
}

MSMQ 队列名称在配置文件的 appSettings 节中指定,如以下示例配置所示。

<appSettings>
<add key="queueName" value=".\private$\ServiceModelSamplesTransacted" />
</appSettings>
注意

队列名称为本地计算机使用圆点 (.),并在使用 System.Messaging 创建队列时在其路径中使用反斜杠分隔符。 Windows Communication Foundation (WCF) 终结点使用具有 net.msmq 方案的队列地址,使用“localhost”来表示本地计算机,并在其路径中使用正斜杠。

客户端创建事务范围。 与队列的通信发生在事务范围之内,从而可将该事务范围视为原子单元,其中所有消息均将发送到队列或者没有任何消息发送到队列。 通过在事务范围上调用 Complete 可以提交事务。

// Create a client.
OrderProcessorClient client = new OrderProcessorClient(); // Create the purchase order.
PurchaseOrder po = new PurchaseOrder();
po.CustomerId = "somecustomer.com";
po.PONumber = Guid.NewGuid().ToString(); PurchaseOrderLineItem lineItem1 = new PurchaseOrderLineItem();
lineItem1.ProductId = "Blue Widget";
lineItem1.Quantity = 54;
lineItem1.UnitCost = 29.99F; PurchaseOrderLineItem lineItem2 = new PurchaseOrderLineItem();
lineItem2.ProductId = "Red Widget";
lineItem2.Quantity = 890;
lineItem2.UnitCost = 45.89F; po.orderLineItems = new PurchaseOrderLineItem[2];
po.orderLineItems[0] = lineItem1;
po.orderLineItems[1] = lineItem2; // Create a transaction scope.
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
// Make a queued call to submit the purchase order.
client.SubmitPurchaseOrder(po);
// Complete the transaction.
scope.Complete();
} // Closing the client gracefully closes the connection and cleans up resources.
client.Close(); Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate client.");
Console.ReadLine();

若要验证事务正在运行,请按照下面的示例代码注释事务范围来修改客户端,重新生成解决方案并运行客户端。

//scope.Complete();

因为事务没有完成,所以消息未发送到队列。

运行示例时,客户端和服务活动将显示在服务和客户端控制台窗口中。 您可以看到服务从客户端接收消息。 在每个控制台窗口中按 Enter 可以关闭服务和客户端。 请注意:由于正在使用队列,因此不必同时启动和运行客户端和服务。 可以先运行客户端,再将其关闭,然后启动服务,这样服务仍然会收到客户端的消息。

The service is ready.
Press <ENTER> to terminate service. Processing Purchase Order: 7b31ce51-ae7c-4def-9b8b-617e4288eafd
Customer: somecustomer.com
OrderDetails
Order LineItem: 54 of Blue Widget @unit price: $29.99
Order LineItem: 890 of Red Widget @unit price: $45.89
Total cost of this order: $42461.56
Order status: Pending

设置、生成和运行示例

  1. 如果先运行服务,则它将检查以确保队列存在。 如果队列不存在,则服务将创建一个队列。 可以先运行服务以创建队列或通过 MSMQ 队列管理器创建一个队列。 执行下面的步骤来在 Windows 2008 中创建队列。

    1. 在 Visual Studio 2012 中打开服务器管理器。

    2. 展开“功能”选项卡。

    3. 右击“私有消息队列”,然后选择“新建”“专用队列”

    4. 选中“事务性”框。

    5. 输入 ServiceModelSamplesTransacted 作为新队列的名称。

  2. 若要生成 C# 或 Visual Basic .NET 版本的解决方案,请按照 生成 Windows Communication Foundation 示例中的说明进行操作。

  3. 若要用单机配置或跨计算机配置来运行示例,请按照 运行 Windows Communication Foundation 示例中的说明进行操作。

默认情况下使用 NetMsmqBinding 启用传输安全。 对于 MSMQ 传输安全存在两个相关属性: 和 。 默认情况下,身份验证模式设置为 Windows,保护级别设置为 Sign。 为了使 MSMQ 提供身份验证和签名功能,MSMQ 必须是域的一部分,并且必须安装 MSMQ 的 Active Directory 集成选项。 如果在未满足这些条件的计算机上运行此示例,将会收到错误。

在加入到工作组或在没有 Active Directory 集成的计算机上运行示例

  1. 如果计算机不是域成员或尚未安装 Active Directory 集成,请将身份验证模式和保护级别设置为 None 以关闭传输安全性,如下面的示例配置代码所示。

    <system.serviceModel>
    <services>
    <service name="Microsoft.ServiceModel.Samples.OrderProcessorService"
    behaviorConfiguration="OrderProcessorServiceBehavior">
    <host>
    <baseAddresses>
    <add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
    </baseAddresses>
    </host>
    <!-- Define NetMsmqEndpoint. -->
    <endpoint
    address="net.msmq://localhost/private/ServiceModelSamplesTransacted"
    binding="netMsmqBinding"
    bindingConfiguration="Binding1"
    contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
    <!-- The mex endpoint is explosed at http://localhost:8000/ServiceModelSamples/service/mex. -->
    <endpoint address="mex"
    binding="mexHttpBinding"
    contract="IMetadataExchange" />
    </service>
    </services> <bindings>
    <netMsmqBinding>
    <binding name="Binding1">
    <security mode="None" />
    </binding>
    </netMsmqBinding>
    </bindings> <behaviors>
    <serviceBehaviors>
    <behavior name="OrderProcessorServiceBehavior">
    <serviceMetadata httpGetEnabled="True"/>
    </behavior>
    </serviceBehaviors>
    </behaviors> </system.serviceModel>
  2. 确保在运行示例前更改服务器和客户端上的配置。

    注意

    securitymode 设置为 None 等效于将 、 和 Message 安全设置为 None

已经过事务处理的 MSMQ 绑定(转载)的更多相关文章

  1. 基于MSMQ绑定的WCF服务实现总结

    一. 创建消息队列    1 1) 创建一个非事物性的私有队列    1 2)设置消息队列访问权限    2 二.创建WCF服务并绑定消息队列    4 1)创建HelloService服务    4 ...

  2. 实战WCF中net.tcp和net.msmq绑定协议

    平时很少写博文的,以前都是转载其他园友的文章,这几天有时间就自己尝试写一些wcf相关的文章,希望能给有需要的人带来一点帮助吧,水平有限再加上初次动手,写得不好还请多多包含!废话不多说了直接进入正题. ...

  3. ASP.NET Core MVC 模型绑定 (转载)

    ASP.NET Core MVC的Model Binding会将HTTP Request数据,以映射的方式对应到参数中.基本上跟ASP.NET MVC差不多,但能Binding的来源更多了一些.本篇将 ...

  4. .NET分布式事务处理总结【下】 - 包含MSMQ的分布式事务处理

    转自:http://www.cnblogs.com/daxnet/archive/2011/03/15/1984995.html .NET直接提供对MSMQ的访问支持,只需要添加System.Mess ...

  5. 浩哥解析MyBatis源码(十二)——binding绑定模块之MapperRegisty

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6758456.html 1.回顾 之前解析了解析模块parsing,其实所谓的解析模块就是为 ...

  6. MyBatis源码解析(十二)——binding绑定模块之MapperRegisty

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6758456.html 1.回顾 之前解析了解析模块parsing,其实所谓的解析模块就是为 ...

  7. WCF(五) 深入理解绑定

    适用于本机WCF-WCF交互性能最佳的绑定: 允许跨主机,但只能用于部署同一台主机上,不能访问命名管道 netNamePipeBinding总结 一 WCF与SOA SOA是一种通过为所有软件提供服务 ...

  8. Centos7网卡绑定的方法

    温和的方式请参考:https://www.cnblogs.com/zzf0305/p/9594093.html 一:传统的bond方式(饭已验证)------------本种的绑定方式比较暴躁 (1) ...

  9. WCF 服务编程 - 常用绑定

    WCF  定义了5中常用的绑定. 一. 绑定 1.基本绑定: 对应于BasicHttpBinding类.基本绑定能够将WCF服务公开为传统的ASMX Web服务,使得原客户端能够与新的服务协作.如果客 ...

随机推荐

  1. memcache入门笔记

    向memcached保存数据时可以指定期限(秒).不指定期限时,memcached按照LRU算法保存数据. 这三个方法的区别如下: 选项 说明 add 仅当存储空间中不存在键相同的数据时才保存 rep ...

  2. Esri的开源JS项目杂谈

    一提到Esri大家首先想到的是庞大的ArcGIS产品大家族,其产品包含从桌面端,到服务器/云端,再到web/移动端.作为一名极客,不聊开源逼格似乎上不去啊.其实,Esri作为一个开放的平台,不仅有稳定 ...

  3. jq 剪切板

    文章链接 http://www.cnblogs.com/lkxsnow/p/5372665.html http://www.w3cfuns.com/notes/17735/020c2e68a60342 ...

  4. 用Redis实现Session功能

    0.什么是Redis Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API ---维基百科 1.与其他用户状态保存方 ...

  5. 如何使用android百度地图离线地图

    1.首先把离线地图放在android工程下的assets里面. 注意:建议离线地图下载通过百度地图APIDEMO去下载,因为到官网上下载的离线地图文件格式不一样,APIDEMO的格式是.dat,而官网 ...

  6. 安卓开发error opening trace file: No such file or directory (2)报错原因

    error opening trace file: No such file or directory (2) 这个问题的出现是因为运行的测试机android系统版本和项目api不一致导致. 改成一样 ...

  7. Unity.Interception(AOP)

            在前面我们学习到的是Unity依赖注入(DI)与统一容器来松散耦合,这个设计已经对我们系统带来了很多的好处.但是我们还会想尝试和遵循单一职责,开放封闭原则.比如我们不应该在我们的Bus ...

  8. C#区分多态和重载-delphi也类似

    Delphi也是基于继承和接口的多态性.

  9. solr DIH 知识梳理

    solr DIH 知识梳理 web.xml中listener配置 <listener> <listener-class>org.apache.solr.handler.data ...

  10. mvc 返回值

    mvc返回值为Model类型 public ActionResult Index(T result) { return View(result); } view中的对象即为页面中的Model数据,之后 ...