2009-06-15 15 views
9

I dati principali consentono di aggiungere più archivi persistenti a un singolo nome NSPersistentStoreCoordinator (ognuno con una configurazione diversa), riunendoli in un unico NSManagedObjectContext. Quello che non sono stato in grado di scoprire è come Core Data gestisce l'atomicità di un'operazione di salvataggio per più negozi.I dati principali archiviano l'atomicità con più negozi

Diciamo che ho due negozi:

NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] init]; 
[coordinator addPersistentStoreWithType:type configuration:@"A" URL:aURL options:nil error:NULL]; 
[coordinator addPersistentStoreWithType:type configuration:@"B" URL:bURL options:nil error:NULL]; 

NSManagedObjectContext *context = [[NSManageObjectContext alloc] init]; 
[context setPersistentStoreCoordinator:coordinator]; 

E allora è il momento di salvare dovrei farlo:

NSError *error = nil; 
BOOL result = [context save:&error]; 

La documentazione afferma che la sequenza degli eventi sarà:

  1. Salva negozio A
  2. Salva negozio B

Cosa succede se il negozio A viene salvato correttamente, ma il negozio B non può essere salvato per qualche motivo? (ad esempio, il file sul disco è stato cancellato o le autorizzazioni lo hanno reso di sola lettura, quel genere di cose). Non riesco a trovare alcuna documentazione che indichi se i dati core ripristinano o meno le modifiche al negozio A.

Mi sembra strano che il grafico dell'oggetto venga lasciato in uno stato incoerente (cioè un negozio aggiornato, uno non), ma alquanto complicato e con molte risorse per eseguire un salvataggio completamente atomico su più negozi. Mi piacerebbe davvero qualche chiarimento qui, forse da qualcuno con più esperienza del sistema!

risposta

5

Alla fine mi sono imbattuto nella risposta in CoreDataErrors.h. C'è un codice di errore:

NSPersistentStoreIncompleteSaveError    = 134040, // one or more of the stores returned an error during save (stores/objects that failed will be in userInfo) 

così sembra che Core Data non tenterà di ripristinare salva dai negozi che hanno avuto successo. E infatti non può fornire atomicità su più negozi. Giusto!

1

Questo suona come qualcosa a cui non sarebbe difficile ottenere una risposta sperimentale ricreando le tue condizioni - hai avuto il tempo di ricreare lo scenario che hai delineato?

vorrei fare questo:

  1. creazione di due negozi SqlLite e la scrittura di una serie di dati per ciascuno dei file.
  2. arresto i negozi
  3. eliminare il secondo file SqlLite
  4. scrivere un facile capire il funzionamento del primo negozio (potrebbe essere meglio fare un inserimento in una tabella e cancellare dall'altro). Combina questo con un'altra operazione sul secondo negozio e quale non dovrebbe riuscire a causa del file mancante 5.Controllare lo stato del primo archivio.

È mia impressione che le modifiche al punto A non vengano annullate, ma rimarrò impressionato da qualsiasi altra risposta.

+0

Non ho ancora provato questo. Sono piuttosto cauto nel considerare il risultato sperimentale come il comportamento documentato, poiché qualsiasi cambiamento nel comportamento sarebbe abbastanza catastrofico per ciò che sto pianificando! Speravo che qualcuno potesse indicarmi un frammento di documentazione sull'argomento che non ero stato in grado di presentare nelle mie ricerche. –

+1

Beh, non riesco a trovare alcuna documentazione. Pianificerei quindi lo scenario peggiore e ipotizzerei che il rollback non funzionasse su due archivi dati e assicurassi che il codice possa gestirlo in qualche modo. Puoi sempre provare a inserire inserti in tabelle fittizie prima di iniziare la tua grande transazione per assicurarti che lo stato dei negozi sia OK. – Grouchal

+0

@Grouchal - Non sono sicuro che il test che stai proponendo funzionerebbe. Per impostazione predefinita, CoreData creerà il secondo archivio in base alle esigenze (se il file è stato chiuso come suggerito). Se il file fosse aperto, il file system unix scollegerebbe il file dal filesystem, ma lo stack CoreData avrebbe comunque accesso al file non collegato fino a quando non fosse stato chiuso. – xyzzycoder

0

Un'opzione per il raggiungimento di transazioni su più origini dati è nota come "commit a due fasi." http://en.wikipedia.org/wiki/Two-phase_commit_protocol

commit a due fasi i sistemi si trovano comunemente in sviluppo delle imprese, a volte inserita all'interno di sistemi di elaborazione delle transazioni http://en.wikipedia.org/wiki/Transaction_processing_monitor

quali Tuxedo http://en.wikipedia.org/wiki/Tuxedo_(software)

CoreData in realtà non è un oggetto-relazionale impresa strumento di mappatura e non credo che sia in grado di commettere in due fasi Alcuni dei tipi di archivio supportati da CoreData e non transazionali o atomici Per supportare un commit a due fasi, è necessario che ogni archivio persistente sia sia transactio nale e atomico.

Problemi correlati