Domanda

Devo inviare una e-mail, scrivere in un file, e chiamare un servizio web.Per mantenere la coerenza, tutti i passaggi devono accadere.Se un passaggio genera un'eccezione o errori, tutte le operazioni devono essere eseguito il rollback.

Prima di andare al rotolamento il mio oggetto di ACIDO motore, ci sono comunemente accettati modelli per l'attuazione di ACIDO semantica a livello di oggetto?

Meglio ancora, ci sono librerie esistenti, che posso usare per il .Piattaforma rete?

Edit: So che l'invio di una e-mail non può essere annullata, ma riesce a connettersi al server SMTP è un motivo per uccidere tutta la transazione.Mi piacerebbe anche questo per essere estensibile, per l'uso con le azioni future.

È stato utile?

Soluzione

L'ultima volta che ho visto qualcosa di simile è stato diversi anni fa. Il poco che mi ricordo a questo proposito è che è stato utilizzato il modello di comando e la memorizzazione di ogni oggetto di comando in una coda. Penso che sia stato uno stack LIFO.

Quindi, se l ' "operazione" non è riuscito, il motore sarebbe pop fuori un oggetto comando, annullare il comando, poi distruggere l'oggetto di comando. Ripetere finché la pila è vuota. Lo stack ottenuto azzerata se la "transazione" ha avuto successo.

Purtroppo, non mi ricordo più di questo.

CSLA.NET implementa uno stack di annullamento simile. Questo è l'unico esempio con il codice che mi viene in mente la parte superiore della mia testa.

Altri suggerimenti

Windows Workflow Foundation ha un concetto di compensazione (utilizzando Composite attività), quando la semantica ACID potrebbero non essere appropriate..Off naturalmente, ha il supporto per le transazioni ACID pure.

  

Una buona domanda è: perché perdere tempo con   Compensazione? Non è una grande ACIDO   transazione con rollback automatico   altrettanto buono? Una transazione ACID è   più appropriata quando si verificano operazioni   all'interno dello stesso database o all'interno della   stesso sistema informativo. È anche   più appropriati operazioni terminano   velocemente. Quando diverse aziende e   servizi sono coinvolti, definendo la   processo in termini di semantica ACID   è spesso difficile. Per essere   isolato e resistente, si deve tenere   tutte le risorse di diverse aziende   bloccato per tutta la durata del compito.   Questo è spesso irragionevole,   soprattutto se il compito è lunga. Per questo   essere coerenti e atomico, è necessario   ad hoc codice di compensazione.

La tecnica più semplice senza basarsi pesantemente su una libreria esterna è prevalenza . Periodicamente checkpoint , utilizzando la serializzazione per scattare un'istantanea del tuo stato, quindi mantenere una ufficiale di serializzazione abbastanza informazioni su ogni operazione collaterale effectful contro i dati di ripetere in un secondo momento. Se qualcosa fa saltare in aria, ricaricare il checkpoint più recente, poi ri-applicare tutti i record diario scritto dopo quel punto.

Per qualcosa di più sofisticato, prova a software di memoria transazionale . Può essere un po 'goffo da implementare in lingue correnti, ma è abbastanza potente e può dare alcune tecniche di concorrenza supplementari pure.

Per le operazioni irreversibili, come l'accesso a un servizio Web o l'invio di una e-mail, è necessario utilizzare transazioni di compensazione : effettuare un'altra chiamata di servizio Web di cancellare o aggiornare i risultati di quello precedente, o forse inviare un altro e-mail consigliando il destinatario che le cose non hanno funzionato come previsto

.

Poiché non è possibile un-inviare una e-mail, ed è relativamente poco costoso per la scrittura di un file, mi basta fare le cose nel giusto ordine:

  1. Prova a scrivere il file/scrivere il file.Se unssuccessful, interrompere, altrimenti:
  2. Chiamare il servizio web.Se l'esito è negativo, eliminare il file e stop, altrimenti:
  3. Inviare e-mail -- email è asincrona, comunque, in modo da è mai veramente sapere se è stato spedito o meno, poiché la maggior parte dei server di posta elettronica sono impostati su riprova per un paio di giorni se si verifica un errore e non si può mai ottenere un riconoscimento che l'e-mail è andato attraverso, anche se era di successo.

Un'idea è quella di utilizzare JMS come 'motore' e si possono utilizzare le transazioni JMS (che possono aderire a operazioni in essere per esempio di transazione DB). Questo inizia a condurre verso un'architettura event-driven asincrono che è probabilmente una buona cosa a meno che non stiamo parlando di applicazioni semplici -., Nel qual caso probabilmente non c'è bisogno di essere porre la domanda

Un esempio di questo sarebbe semplice la creazione di account. Per questo si vuole persistere informazioni account al DB e anche inviare all'utente una e-mail per l'attivazione - ma li volete nella stessa transazione per ovvi motivi

.

Non si dovrebbe mettere e-mail il codice di invio all'interno della transazione perché, anche se è possibile inviare l'e-mail - transazione db commit potrebbe non riuscire per un motivo o un altro. Inoltre, non dovrebbe mettere l'invio di email al di fuori della transazione (dopo il commit), perché l'invio di e-mail potrebbe non riuscire portando ad un account orfano.

Quindi, per utilizzare JMS in questo scenario - mettere JMS codice di invio all'interno della transazione DB e farlo aderire a tale operazione. Si sono garantiti recapito dei messaggi. D'altra estremità avere qualcosa che consumano la coda di invio di email fuori. In caso di fallimento invia, migliore opzione è quella di log / generare un avviso - JMS sarà rollback e mettere di nuovo un messaggio nella coda per il consumo dopo. vale a dire per cercare di inviare di nuovo email una volta che avete spera fisso qualunque sia il problema.

La cosa fondamentale è - Record DB è coerente e-mail viene inviata alla fine

.

Due pensieri:

Inoltre, un progetto sperimentale STM .NET è stato recentemente rilasciato . Questo progetto aggiunge memoria transazione per C #. In realtà modifica il CLR a sostegno di questa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top