Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
В примере Transacted показано, как выполнять транзакционные сообщения в очереди с помощью очереди сообщений (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();
Так как транзакция не завершена, сообщения не отправляются в очередь.
При запуске примера действия клиента и службы отображаются как в окнах службы, так и в консоли клиента. Вы можете увидеть, как служба получает сообщения от клиента. Нажмите клавишу ВВОД в каждом окне консоли, чтобы завершить работу службы и клиента. Обратите внимание, что поскольку используется очередь, клиенту и службе не обязательно работать одновременно. Вы можете запустить клиент, завершить работу, а затем запустить службу, и она по-прежнему получает сообщения.
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
Настройка, сборка и запуск примера
Убедитесь, что вы выполнили процедуру настройки One-Time для образцов Windows Communication Foundation.
Если сначала запущена служба, она проверит наличие очереди. Если очередь отсутствует, служба создаст ее. Сначала можно запустить службу для создания очереди или создать ее с помощью диспетчера очередей MSMQ. Выполните следующие действия, чтобы создать очередь в Windows 2008.
Откройте диспетчер серверов в Visual Studio 2012.
Разверните вкладку "Функции" .
Щелкните правой кнопкой мыши Очереди частных сообщенийи выберите Создать, Частную очередь.
Установите флажок транзакционная.
Введите
ServiceModelSamplesTransactedв качестве имени новой очереди.
Чтобы создать версию решения на C# или Visual Basic .NET, следуйте инструкциям по сборке примеров Windows Communication Foundation .
Чтобы запустить пример в конфигурации с одним или несколькими компьютерами, следуйте инструкциям в разделе "Примеры Windows Communication Foundation".
По умолчанию в NetMsmqBindingвключена транспортная безопасность. Имеются два соответствующих свойства для безопасности транспорта MSMQ: MsmqAuthenticationMode и MsmqProtectionLevel. По умолчанию режим проверки подлинности задан как Windows, а уровень защиты установлен как Sign. Чтобы MSMQ предоставляла функцию проверки подлинности и подписывания, она должна быть частью домена, а параметр интеграции Active Directory для MSMQ должен быть установлен. Если вы запускаете этот пример на компьютере, который не соответствует этим критериям, вы получите сообщение об ошибке.
Запуск примера на компьютере, присоединенном к рабочей группе или без интеграции Active Directory
Если компьютер не является частью домена или не имеет интеграции 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 exposed 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>Перед запуском примера убедитесь, что вы измените конфигурацию как на сервере, так и на клиенте.
Замечание
Установка
security modeравносильна установкеNone, а также установке параметров MsmqAuthenticationMode, MsmqProtectionLevel, иMessageбезопасности наNone.