Condividi tramite


Ricevere messaggi modificati sui dati basati sul polling nel database Oracle usando il modello di canale WCF

È possibile configurare l'adapter Microsoft BizTalk per Oracle Database per eseguire il polling di una tabella o una visualizzazione di database Oracle per eventuali modifiche ai dati. Per eseguire un'operazione di polling di questo tipo, l'adapter esegue periodicamente una query SQL su una tabella o una vista Oracle seguita da un blocco di codice PL/SQL facoltativo. I risultati della query SQL vengono quindi restituiti dall'adapter di database Oracle al codice come set di risultati fortemente tipizzato in un'operazione POLLINGSTMT in ingresso. Per altre informazioni sul meccanismo usato per configurare ed eseguire il polling in un database Oracle usando l'adapter Oracle Database, vedere Ricevere messaggi modificati dei dati basati sul polling nell'adapter Oracle Database. È consigliabile leggere questo argomento prima di procedere.

È possibile configurare l'adapter Oracle Database per eseguire il polling e la tabella o la visualizzazione del database Oracle impostando le proprietà di associazione in un'istanza di OracleDBBinding. Nel modello di canale WCF si usa quindi questa associazione per creare un listener del canale da cui è possibile ottenere un canale IInputChannel per ricevere l'operazione POLLINGSTMT dall'adapter.

Per una panoramica di come ricevere operazioni usando un IInputChannel in WCF, vedere Programmazione del servizio Channel-Level.

Le sezioni di questo argomento forniscono informazioni utili per eseguire il polling su tabelle e viste del database Oracle usando il modello di canale WCF.

Utilizzo del messaggio di richiesta POLLINGSTMT

L'adapter richiama l'operazione POLLINGSTMT nel codice per eseguire il polling del database Oracle. Ovvero, l'adapter invia un messaggio di richiesta POLLINGSTMT ricevuto tramite una forma di canale IInputChannel . Il messaggio di richiesta POLLINGSTMT contiene il set di risultati della query specificata dalla proprietà di associazione PollingStatement . È possibile usare il messaggio POLLINGSTMT in uno dei due modi seguenti:

  • Per utilizzare il messaggio usando il flusso node-value, è necessario chiamare il metodo WriteBodyContents nel messaggio di risposta e passarlo a un oggetto XmlDictionaryWriter che implementa lo streaming node-value.

  • Per utilizzare il messaggio usando il flusso del nodo, è possibile chiamare GetReaderAtBodyContents nel messaggio di risposta per ottenere un xmlReader.

    In genere si usa lo streaming node-value per usare i set di risultati che contengono colonne di dati Oracle LOB.

    Per altre informazioni sulla struttura dei messaggi dell'operazione POLLINGSTMT, vedere Schemi dei messaggi per le operazioni di polling.

    Per altre informazioni sul modo in cui l'adattatore Oracle Database supporta lo streaming sui dati LOB, vedere Streaming di tipi di dati di oggetti di grandi dimensioni nella scheda Oracle Database.

    Per altre informazioni sull'implementazione dello streaming node-value nel codice per supportare lo streaming end-to-end dei dati LOB, vedere Streaming di tipi di dati LOB del database Oracle tramite il modello di canale WCF.

Informazioni sugli esempi usati in questo argomento

L'esempio in questo argomento usa SCOTT. Tabella ACCOUNTACTIVITY e SCOTT. ACCOUNT_PKG. PROCESS_ACTIVITY funzione. Uno script per generare questi artefatti viene fornito con gli esempi. Nell'esempio vengono eseguite le operazioni seguenti:

  • Nell'ambito dell'istruzione di polling selezionare tutti i record della tabella ACCOUNTACTIVITY e visualizzati nella console.

  • Nell'ambito dell'istruzione post poll, nell'esempio viene richiamata la funzione PROCESS_ACTIVITY che sposta tutti i record dalla tabella ACCOUNTACTIVITY alla tabella ACTIVITYHISTORY.

  • I poll successivi nella tabella ACCOUNTACTIVITY non restituiscono record. Tuttavia, se si vuole che l'esempio restituisca più record come parte dell'operazione di polling, è necessario inserire alcuni record nella tabella ACCOUNTACTIVITY. È possibile farlo eseguendo lo script more_activity_data.sql fornito con gli esempi.

    Per altre informazioni sugli esempi, vedere Esempi di adapter.

Come si esegue il polling di un database Oracle usando un IInputChannel?

Per eseguire il polling di una tabella o una vista di database Oracle per ricevere messaggi di modifica dei dati usando il modello di canale WCF, seguire questa procedura.

Per ricevere messaggi modificati dai dati usando un IInputChannel

  1. Creare un progetto Visual C# in Visual Studio. Per questo argomento, creare un'applicazione console.

  2. Nella Esplora soluzioni aggiungere riferimento a Microsoft.Adapters.OracleDB, Microsoft.ServiceModel.Channels, System.ServiceModele System.Runtime.Serialization.

  3. Aprire il file Program.cs e aggiungere gli spazi dei nomi seguenti:

    • Microsoft.Adapters.OracleDB

    • Microsoft.ServiceModel.Channels

    • System.ServiceModel

    • System.ServiceModel.Description

    • System.ServiceModel.Channels

    • System.Xml

    • System.Runtime.Serialization

    • System.IO

    • Microsoft.ServiceModel.Channels.Common

  4. Creare un'istanza di OracleDBBinding e impostare le proprietà di associazione necessarie per configurare il polling. È necessario impostare almeno le proprietà di associazione InboundOperationType, PollingStatement e PollingInterval . Per questo esempio, si imposta anche la proprietà di associazione PostPollStatement . Per altre informazioni sulle proprietà di associazione usate per configurare il polling, vedere Ricevere messaggi modificati dei dati basati sul polling nell'adattatore Oracle Database.

    OracleDBBinding binding = new OracleDBBinding();  
    binding.InboundOperationType = InboundOperation.Polling;  
    binding.PollingInterval = 30;  
    binding.PollingStatement = "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE";  
    binding.PostPollStatement = "BEGIN ACCOUNT_PKG.PROCESS_ACTIVITY(); END;"  
    
  5. Creare una raccolta di parametri di associazione e impostare le credenziali.

    ClientCredentials credentials = new ClientCredentials();  
    credentials.UserName.UserName = "SCOTT";  
    credentials.UserName.Password = "TIGER";  
    
    BindingParameterCollection bindingParams = new BindingParameterCollection();  
    bindingParams.Add(credentials);  
    
  6. Creare un listener del canale e aprirlo. Si crea il listener richiamando il metodo IInputChannel<> in OracleDBBinding. È possibile modificare lo spazio dei nomi di destinazione per l'operazione POLLINGSTMT impostando la proprietà PollingId nell'URI di connessione. Per altre informazioni sull'URI di connessione della scheda, vedere Creare l'URI di connessione del database Oracle.

    IChannelListener<IInputChannel> listener = binding.BuildChannelListener<IInputChannel>(connectionUri, bindingParams);  
    listener.Open();  
    
  7. Ottenere un canale IInputChannel richiamando il metodo AcceptChannel nel listener e aprirlo.

    IInputChannel channel = listener.AcceptChannel();  
    channel.Open();  
    
  8. Richiamare Ricezione nel canale per ottenere il messaggio POLLINGSTMT successivo dall'adapter.

    Message message = channel.Receive();  
    
  9. Utilizzare il set di risultati restituito dall'operazione POLLINGSTMT. È possibile utilizzare il messaggio usando xmlReader o xmlDictionaryWriter.

    XmlReader reader = message.GetReaderAtBodyContents();  
    
  10. Chiudere il canale al termine dell'elaborazione della richiesta.

    channel.Close()  
    

    Importante

    È necessario chiudere il canale dopo aver completato l'elaborazione dell'operazione POLLINGSTMT. L'errore di chiudere il canale può influire sul comportamento del codice.

  11. Chiudere il listener al termine della ricezione di messaggi modificati dai dati.

    listener.Close()  
    

    Importante

    La chiusura del listener non chiude i canali creati usando il listener. È necessario chiudere in modo esplicito ogni canale creato usando il listener.

Esempio

Nell'esempio seguente viene illustrato come configurare l'adapter Oracle Database per eseguire il polling di tabelle e viste del database Oracle e ricevere l'operazione POLLLINGSTMT usando il modello di canale WCF. Il set di risultati restituito nell'operazione POLLINGSTMT viene scritto nella console usando un xmlReader.

using System;  
using System.Collections.Generic;  
using System.Text;  
  
// Add WCF, WCF LOB Adapter SDK, and Oracle Database adapter namepaces  
using System.ServiceModel;  
using System.ServiceModel.Description;  
using Microsoft.ServiceModel.Channels;  
using Microsoft.Adapters.OracleDB;  
  
// Add this namespace for channel model  
using System.ServiceModel.Channels;  
  
using System.Xml;  
using System.Runtime.Serialization;  
using System.IO;  
  
// Include this namespace for the WCF LOB Adapter SDK and Oracle exceptions  
using Microsoft.ServiceModel.Channels.Common;  
  
namespace OraclePollingCM  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            Uri connectionUri = new Uri("oracleDB://ADAPTER/");  
  
            IChannelListener<IInputChannel> listener = null;  
            IInputChannel channel = null;  
  
            // set timeout to receive POLLINGSTMT message  
            TimeSpan messageTimeout = new TimeSpan(0, 0, 30);  
  
            Console.WriteLine("Sample Started");  
  
            try  
            {  
                // Create a binding: specify the InboundOperationType, PollingInterval (in seconds), the           
                // PollingStatement,and the PostPollStatement.  
                OracleDBBinding binding = new OracleDBBinding();  
                binding.InboundOperationType = InboundOperation.Polling;  
                binding.PollingInterval = 30;  
                binding.PollingStatement = "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE";  
                binding.PostPollStatement = "BEGIN ACCOUNT_PKG.PROCESS_ACTIVITY(); END;";  
  
                // Create a binding parameter collection and set the credentials  
                ClientCredentials credentials = new ClientCredentials();  
                credentials.UserName.UserName = "SCOTT";  
                credentials.UserName.Password = "TIGER";  
  
                BindingParameterCollection bindingParams = new BindingParameterCollection();  
                bindingParams.Add(credentials);  
  
                Console.WriteLine("Opening listener");  
                // get a listener  from the binding  
                listener = binding.BuildChannelListener<IInputChannel>(connectionUri, bindingParams);  
                listener.Open();  
  
                Console.WriteLine("Opening channel");  
                // get a channel from the listener  
                channel = listener.AcceptChannel();  
                channel.Open();  
  
                Console.WriteLine("Channel opened -- waiting for polled data");  
                Console.WriteLine("Receive request timeout is {0}", messageTimeout);  
  
                // Poll five times with the specified message timeout   
                // If a timeout occurs polling will be aborted  
                for (int i = 0; i < 5; i++)  
                {  
                    Console.WriteLine("Polling: " + i);  
                    Message message = null;  
                    XmlReader reader = null;  
                    try  
                    {  
                        //Message is received so process the results  
                        message = channel.Receive(messageTimeout);  
                    }  
                    catch (System.TimeoutException toEx)  
                    {  
                        Console.WriteLine("\nNo data for request number {0}: {1}", i + 1, toEx.Message);  
                        continue;  
                    }  
  
                    // Get the query results using an XML reader  
                    try  
                    {  
                        reader = message.GetReaderAtBodyContents();  
                    }  
                    catch (Exception ex)  
                    {  
                        Console.WriteLine("Exception :" + ex);  
                        throw;  
                    }  
  
                    // Write the TID, ACCOUNT, AMOUNT, and TRANSDATE for each record to the Console  
                    Console.WriteLine("\nPolling data received for request number {0}", i+1);  
                    Console.WriteLine("Tx ID\tACCOUNT\tAMOUNT\tTx DATE");  
  
                    while (reader.Read())  
                    {  
                        if (reader.IsStartElement())  
                        {  
                            switch (reader.Name)  
                            {  
                                case "POLLINGSTMTRECORD":  
                                    Console.Write("\n");  
                                    break;  
  
                                case "TID":  
                                    reader.Read();  
                                    Console.Write(reader.ReadString() + "\t");  
                                    break;  
  
                                case "ACCOUNT":  
                                    reader.Read();  
                                    Console.Write(reader.ReadString() + "\t");  
                                    break;  
                                case "AMOUNT":  
                                    reader.Read();  
                                    Console.Write(reader.ReadString() + "\t");  
                                    break;  
  
                                case "TRANSDATE":  
                                    reader.Read();  
                                    Console.Write(reader.ReadString() + "\t");  
                                    break;  
  
                                default:  
                                    break;  
                            }  
                        }  
                    }  
  
                    // return the cursor  
                    Console.WriteLine();  
  
                    // close the reader  
                    reader.Close();  
  
                    //            To save the polling data to a file you can REPLACE the code above with the following  
                    //  
                    //            XmlDocument doc = new XmlDocument();  
                    //            doc.Load(reader);  
                    //            using (XmlWriter writer = XmlWriter.Create("PollingOutput.xml"))  
                    //            {  
                    //                doc.WriteTo(writer);  
                    //            }  
                    message.Close();  
                }  
  
                Console.WriteLine("\nPolling done -- hit <RETURN> to finish");  
                Console.ReadLine();  
            }  
            catch (TargetSystemException tex)  
            {  
                Console.WriteLine("Exception occurred on the Oracle Database");  
                Console.WriteLine(tex.InnerException.Message);  
            }  
            catch (ConnectionException cex)  
            {  
                Console.WriteLine("Exception occurred connecting to the Oracle Database");  
                Console.WriteLine(cex.InnerException.Message);  
            }  
            catch (Exception ex)  
            {  
                Console.WriteLine("Exception is: " + ex.Message);  
                if (ex.InnerException != null)  
                {  
                    Console.WriteLine("Inner Exception is: " + ex.InnerException.Message);  
                }  
            }  
            finally  
            {  
                // IMPORTANT: close the channel and listener to stop polling  
                if (channel != null)  
                {  
                    if (channel.State == CommunicationState.Opened)  
                        channel.Close();  
                    else  
                        channel.Abort();  
                }  
  
                if (listener != null)  
                {  
                    if (listener.State == CommunicationState.Opened)  
                        listener.Close();  
                    else  
                        listener.Abort();  
                }  
            }  
        }  
    }  
}  

Vedere anche

Sviluppare applicazioni di Database Oracle usando il modello di canale WCF