2012-02-15 15 views
6

Sto esponendo un servizio WCF tramite un basicHttpBinding che esegue diverse operazioni su un database.WCF basicHttpBinding: rollback quando la risposta al client non riesce

Desidero garantire che se il client non riceve la risposta, le operazioni del database vengono ripristinate (senza flusso di transazioni tramite WCF). E.g. il client chiama il metodo "DoX" che viene eseguito sul server ma prima che sia terminato il client si blocca. Le operazioni del database dovrebbero quindi essere ripristinate non appena la risposta non può essere inviata al client.

C'è un modo per farlo? L'attributo [OperationBehavior(TransactionScopeRequired=true)] funziona in questo modo? C'è la possibilità di gestire gli errori di comunicazione sul lato server?

Update 1: Sembra [OperationBehavior(TransactionScopeRequired=true)] impegna la transazione prima che la risposta è inviare al cliente e quindi non può essere utilizzato per eseguire un rollback se il cliente non riceve la risposta.

Aggiornamento 2: Per dirla chiaramente ancora una volta, non ho la necessità per la transazione di interagire in qualche modo con il lato client. Il cliente non deve conoscere la transazione, ha la possibilità di annullarlo o eseguirlo, né dovrebbe transitare alcuna transazione attraverso l'associazione. L'area solo deve essere ripristinata sul lato server se il canale di trasporto non è in grado di recapitare il messaggio al client di destinazione. Con il caso di TCP/IP queste informazioni dovrebbero essere prontamente disponibili per il server. (Nessun ACK del pacchetto TCP inviare al client)

Quindi, un flusso di esecuzione ipotetica sul lato server (notare la mancanza di lato client) dovrebbe essere:

Receive client request 

Start transaction 

Execute all logic inside the service operation 

Send reply back to client 

if (reply.failedToReceive) { transaction.Rollback() } // due to a failing TCP/IP transmission 
+0

Perché è necessario utilizzare basiHttpBinding? wsHttpBinding ti darà questo. –

+0

@JustinDearing: i client che accedono al servizio non supportano wsHttpBinding. – GaussZ

+0

per curiosità qual è la piattaforma client? Http://wso2.com ha un client di sapone per questo? –

risposta

1

Non c'è una risposta facile questa domanda. Stai chiedendo un comportamento implementato in WS- * ma fatto usando SOAP di base. Penso che la tua unica opzione se NON REALMENTE puoi passare a wsHttpBinding o usare duplex come suggerito da @Trevor Pilley è provare a simulare il comportamento di WS-Transaction nel tuo protocollo personalizzato basato sul SOAP di base.

Si dovrebbe essere in grado di ottenere una certa semplificazione sopra la specifica completa WS-Transaction perché

  • Sarà probabilmente solo bisogno di supportare le transazioni nel corso di un singolo servizio - non si farà una transazione distribuita su più indipendente servizi
  • non dovranno sostenere sia a breve che a transazioni (WS-AtomicTransaction), così come le operazioni di gestione a lungo (WS-BusinessActivity) probaby transazioni atomiche farebbero
  • non avrebbe bisogno di supportare qualsiasi tipo di modello di estensibilità (WS-Coordination)
  • Non è necessario implementare un modello di individuazione/metadati che descriva il protocollo (ad es. come WSDL) perché codificherebbe il comportamento del protocollo direttamente nel client e nel servizio.

Tuttavia, è probabile che siano necessari elementi di WS-Coordination e WS-AtomicTransaction.Questo non è un compito semplice con qualsiasi mezzo e sarà facile perdere qualcosa di sottile che potrebbe causare il mancato rollback o (altrettanto grave) distruggere le prestazioni del servizio con blocchi di lunga durata su tutto il database a causa di client arrestati.

Come ho detto, questo è un comportamento complesso e se non è possibile utilizzare protocolli standardizzati pronti all'uso, non esiste una risposta semplice.

+0

Ho aggiunto ulteriori chiarimenti alla domanda. Voglio solo eseguire il rollback della transazione se la trasmissione del messaggio di risposta dal client al server non riesce. Il client non entra mai in gioco, o solo nella misura in cui il client non riesce a ricevere i pacchetti TCP/IP. – GaussZ

+1

Ma come è il servizio sapere se il client ha ricevuto il messaggio? Non dovrebbe notificare il servizio in una seconda chiamata, ad esempio, a un metodo di commit che passa in un ID transazione ricevuto dalla risposta alla chiamata di servizio iniziale ... –

+0

Vedo che cosa stai pensando con il TCP/IP ACK ma si sta utilizzando HTTP e non penso che il TCP/IP sottostante sia esposto da WCF. e infatti, HTTP non è necessariamente basato su TCP/IP. Qualsiasi trasporto affidabile lo farà. Questo probabilmente implica che un'implementazione che obbedisca rigorosamente allo standard non esponga il protocollo filo sottostante. –

Problemi correlati