Sdílet prostřednictvím


Tok transakcí do služeb pracovních postupů a mimo ně

Služby pracovních postupů a klienti se mohou účastnit transakcí. Aby se operace služby stala součástí okolí transakce, umístěte Receive aktivitu v rámci TransactedReceiveScope aktivity. Všechna volání provedená určitou aktivitou Send nebo aktivitou SendReply v rámci TransactedReceiveScope transakce bude provedena také v okolí transakce. Klientská aplikace pracovního postupu může vytvořit okolí transakce pomocí TransactionScope aktivity a volání operací služby pomocí okolí transakce. Toto téma vás provede vytvořením služby pracovního postupu a klienta pracovního postupu, který se účastní transakcí.

Upozorňující

Pokud je instance služby pracovního postupu načtena v rámci transakce a pracovní postup obsahuje Persist aktivitu, instance pracovního postupu bude blokovat, dokud transakce nevysadí časový limit.

Důležité

Pokaždé, když použijete příkaz TransactedReceiveScope , který se doporučuje umístit do pracovního postupu všechny příjemce v rámci TransactedReceiveScope aktivit.

Důležité

Při použití TransactedReceiveScope a doručení zpráv v nesprávném pořadí se pracovní postup při pokusu o doručení první zprávy mimo objednávku přeruší. Musíte se ujistit, že pracovní postup je vždy v konzistentním zastavování, když idles pracovního postupu. To vám umožní restartovat pracovní postup z předchozího bodu trvalosti v případě přerušení pracovního postupu.

Vytvoření sdílené knihovny

  1. Vytvořte nové prázdné řešení sady Visual Studio.

  2. Přidejte nový projekt knihovny tříd s názvem Common. Přidejte odkazy na následující sestavení:

    • System.Activities.dll

    • System.ServiceModel.dll

    • System.ServiceModel.Activities.dll

    • System.Transactions.dll

  3. Přidejte do projektu novou třídu volanou PrintTransactionInfoCommon . Tato třída je odvozena z NativeActivity a přetížení Execute metody.

    using System;  
    using System;  
    using System.Activities;  
    using System.Transactions;  
    
    namespace Common  
    {  
        public class PrintTransactionInfo : NativeActivity  
        {  
            protected override void Execute(NativeActivityContext context)  
            {  
                RuntimeTransactionHandle rth = context.Properties.Find(typeof(RuntimeTransactionHandle).FullName) as RuntimeTransactionHandle;  
    
                if (rth == null)  
                {  
                    Console.WriteLine("There is no ambient RuntimeTransactionHandle");  
                }  
    
                Transaction t = rth.GetCurrentTransaction(context);  
    
                if (t == null)  
                {  
                    Console.WriteLine("There is no ambient transaction");  
                }  
                else  
                {  
                    Console.WriteLine("Transaction: {0} is {1}", t.TransactionInformation.DistributedIdentifier, t.TransactionInformation.Status);  
                }  
            }  
        }  
    
    }  
    

    Jedná se o nativní aktivitu, která zobrazuje informace o okolí transakce a používá se jak ve službě, tak v klientských pracovních postupech používaných v tomto tématu. Sestavte řešení, aby byla tato aktivita dostupná v části Společné v sadě nástrojů.

Implementace služby pracovního postupu

  1. Přidejte do projektu novou službu pracovního postupu WCF, která je Common volánaWorkflowService. Chcete-li to provést, klikněte pravým tlačítkem na Common projekt, vyberte Přidat, Nová položka ..., Vyberte pracovní postup v části Nainstalované šablony a vyberte Služba pracovního postupu WCF.

    Adding a Workflow Service

  2. Odstraňte výchozí ReceiveRequest hodnoty a SendResponse aktivity.

  3. WriteLine Přetáhněte aktivitu do Sequential Service aktivity. Nastavte text vlastnost tak "Workflow Service starting ..." , jak je znázorněno v následujícím příkladu.

    ! [Přidání aktivity WriteLine do aktivity sekvenční služby(./media/flowing-transactions-into-and-out-of-workflow-services/add-writeline-sequential-service.jpg)

  4. Přetáhněte akci za aktivitou TransactedReceiveScopeWriteLine . TransactedReceiveScope Aktivitu najdete v části Zasílání zpráv v sadě nástrojů. Aktivita TransactedReceiveScope se skládá ze dvou částí Požadavek a Text. Část Požadavek obsahuje Receive aktivitu. Část Body obsahuje aktivity, které se mají provést v rámci transakce po přijetí zprávy.

    Adding a TransactedReceiveScope activity

  5. TransactedReceiveScope Vyberte aktivitu a klikněte na tlačítko Proměnné. Přidejte následující proměnné.

    Adding variables to the TransactedReceiveScope

    Poznámka:

    Datová proměnná, která je tam ve výchozím nastavení, můžete odstranit. Můžete také použít existující proměnnou popisovače.

  6. Receive Přetáhněte aktivitu v části TransactedReceiveScope Požadavek aktivity. Nastavte následující vlastnosti:

    Vlastnost Hodnota
    Cancreateinstance True (zaškrtněte políčko)
    OperationName StartSample
    ServiceContractName ITransactionSample

    Pracovní postup by měl vypadat takto:

    Adding a Receive activity

  7. Klikněte na odkaz Definovat... v aktivitě Receive a proveďte následující nastavení:

    Setting message settings for the Receive activity

  8. Sequence Přetáhněte aktivitu do části Tělo objektu TransactedReceiveScope. Sequence V rámci aktivity přetáhněte dvě WriteLine aktivity a nastavte Text vlastnosti, jak je znázorněno v následující tabulce.

    Aktivita Hodnota
    1. WriteLine "Služba: Příjem dokončeno"
    2. WriteLine "Služba: Received = " + requestMessage

    Pracovní postup by teď měl vypadat takto:

    Sequence after adding WriteLine activities

  9. PrintTransactionInfo Přetáhněte aktivitu za druhou WriteLine aktivitu v textuTransactedReceiveScope aktivity.

    Sequence after adding PrintTransactionInfo

  10. Assign Přetáhněte aktivitu za PrintTransactionInfo aktivitu a nastavte její vlastnosti podle následující tabulky.

    Vlastnost Hodnota
    Do replyMessage
    Hodnota "Služba: Odesílání odpovědí."
  11. Přetáhněte aktivitu za aktivitou WriteLineAssign a nastavte její Text vlastnost na "Služba: Zahájit odpověď".

    Pracovní postup by teď měl vypadat takto:

    After adding Assign and WriteLine

  12. Klikněte pravým tlačítkem myši na Receive aktivitu a vyberte Vytvořit SendReply a vložte ji za poslední WriteLine aktivitu. Klikněte na odkaz Definovat... v aktivitě SendReplyToReceive a proveďte následující nastavení.

    Reply message settings

  13. Přetáhněte aktivitu za aktivitou WriteLineSendReplyToReceive a nastavte její Text vlastnost na "Service: Reply sent" (Služba: Odpověď odeslána).

  14. WriteLine Přetáhněte aktivitu v dolní části pracovního postupu a nastavte její Text vlastnost na "Service: Workflow end, press ENTER to exit" (Služba: Pracovní postup končí).

    Dokončený pracovní postup služby by měl vypadat takto:

    Complete Service Workflow

Implementace klienta pracovního postupu

  1. Přidejte do projektu novou aplikaci pracovního postupu WCF, která je Common volánaWorkflowClient. Chcete-li to provést, klikněte pravým tlačítkem myši na Common projekt, vyberte Přidat, Nová položka ..., Vyberte pracovní postup v části Nainstalované šablony a vyberte Aktivita.

    Add an Activity project

  2. Sequence Přetáhněte aktivitu na návrhovou plochu.

  3. Sequence V rámci aktivity přetáhněte WriteLine aktivitu a nastavte její Text vlastnost na "Client: Workflow starting". Pracovní postup by teď měl vypadat takto:

    Add a WriteLine activity

  4. TransactionScope Přetáhněte aktivitu za aktivitouWriteLine. TransactionScope Vyberte aktivitu, klikněte na tlačítko Proměnné a přidejte následující proměnné.

    Add variables to the TransactionScope

  5. Sequence Přetáhněte aktivitu do těla TransactionScope aktivity.

  6. PrintTransactionInfo Přetažení aktivity v rámciSequence

  7. Přetáhněte aktivitu za aktivitou WriteLinePrintTransactionInfo a nastavte její Text vlastnost na "Client: Beginning Send". Pracovní postup by teď měl vypadat takto:

    Adding Client: Beginning Send activities

  8. Přetáhněte aktivitu za aktivitou SendAssign a nastavte následující vlastnosti:

    Vlastnost Hodnota
    EndpointConfigurationName workflowServiceEndpoint
    OperationName StartSample
    ServiceContractName ITransactionSample

    Pracovní postup by teď měl vypadat takto:

    Setting the Send activity properties

  9. Klikněte na odkaz Definovat... a proveďte následující nastavení:

    Send activity message settings

  10. Klikněte pravým tlačítkem myši na Send aktivitu a vyberte Vytvořit receiveReply. Aktivita ReceiveReply se automaticky umístí po aktivitě Send .

  11. Klikněte na definovat... odkaz na ReceiveReplyForSend aktivity a proveďte následující nastavení:

    Setting the ReceiveForSend message settings

  12. WriteLine Přetáhněte aktivitu mezi Send aktivitami a ReceiveReply aktivitami a nastavte její Text vlastnost na "Client: Send complete" (Klient: Odeslat dokončeno).

  13. Přetáhněte aktivitu za aktivitou WriteLineReceiveReply a nastavte její Text vlastnost na "Client side: Reply received = " + replyMessage

  14. PrintTransactionInfo Přetáhněte aktivitu za aktivitouWriteLine.

  15. WriteLine Přetáhněte aktivitu na konec pracovního postupu a nastavte jeho Text vlastnost na "Klient pracovní postup končí". Dokončený pracovní postup klienta by měl vypadat jako v následujícím diagramu.

    The completed client workflow

  16. Sestavte řešení.

Vytvoření aplikace služby

  1. Přidejte do řešení nový projekt konzolové aplikace volaný Service . Přidejte odkazy na následující sestavení:

    1. System.Activities.dll

    2. System.ServiceModel.dll

    3. System.ServiceModel.Activities.dll

  2. Otevřete vygenerovaný soubor Program.cs a následující kód:

          static void Main()  
          {  
              Console.WriteLine("Building the server.");  
              using (WorkflowServiceHost host = new WorkflowServiceHost(new DeclarativeServiceWorkflow(), new Uri("net.tcp://localhost:8000/TransactedReceiveService/Declarative")))  
              {
                  //Start the server  
                  host.Open();  
                  Console.WriteLine("Service started.");  
    
                  Console.WriteLine();  
                  Console.ReadLine();  
                  //Shutdown  
                  host.Close();  
              };
          }  
    
  3. Do projektu přidejte následující soubor app.config.

    <?xml version="1.0" encoding="utf-8" ?>  
    <!-- Copyright © Microsoft Corporation.  All rights reserved. -->  
    <configuration>  
        <system.serviceModel>  
            <bindings>  
                <netTcpBinding>  
                    <binding transactionFlow="true" />  
                </netTcpBinding>  
            </bindings>  
        </system.serviceModel>  
    </configuration>  
    

Vytvoření klientské aplikace

  1. Přidejte do řešení nový projekt konzolové aplikace volaný Client . Přidejte odkaz na System.Activities.dll.

  2. Otevřete soubor program.cs a přidejte následující kód.

    class Program  
    {  
    
        private static AutoResetEvent syncEvent = new AutoResetEvent(false);  
    
        static void Main(string[] args)  
        {  
            //Build client  
            Console.WriteLine("Building the client.");  
            WorkflowApplication client = new WorkflowApplication(new DeclarativeClientWorkflow());  
            client.Completed = Program.Completed;  
            client.Aborted = Program.Aborted;  
            client.OnUnhandledException = Program.OnUnhandledException;  
            //Wait for service to start  
            Console.WriteLine("Press ENTER once service is started.");  
            Console.ReadLine();  
    
            //Start the client
            Console.WriteLine("Starting the client.");  
            client.Run();  
            syncEvent.WaitOne();  
    
            //Sample complete  
            Console.WriteLine();  
            Console.WriteLine("Client complete. Press ENTER to exit.");  
            Console.ReadLine();  
        }  
    
        private static void Completed(WorkflowApplicationCompletedEventArgs e)  
        {  
            Program.syncEvent.Set();  
        }  
    
        private static void Aborted(WorkflowApplicationAbortedEventArgs e)  
        {  
            Console.WriteLine("Client Aborted: {0}", e.Reason);  
            Program.syncEvent.Set();  
        }  
    
        private static UnhandledExceptionAction OnUnhandledException(WorkflowApplicationUnhandledExceptionEventArgs e)  
        {  
            Console.WriteLine("Client had an unhandled exception: {0}", e.UnhandledException);  
            return UnhandledExceptionAction.Cancel;  
        }  
    }  
    

Viz také