2009-06-15 4 views
9

Основные данные позволяют добавлять несколько постоянных хранилищ в одно имя(каждый с другой конфигурацией), тем самым объединяя их в один NSManagedObjectContext. То, что я не смог выяснить, - это то, как Core Data обрабатывает атомарность операции сохранения для нескольких магазинов.Основные данные хранилища данных с несколькими магазинами

Скажем, у меня есть два магазина:

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]; 

А потом пришло время, чтобы спасти меня сделать это:

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

В документации говорится, что последовательность событий будет:

  1. Сохранить магазин A
  2. Сохранить магазин B

Что делать, если магазин A сохраняет правильно, но магазин B не может сэкономить по какой-либо причине? (например, файл на диске был удален, или разрешения сделали его доступным только для чтения). Я не могу найти какую-либо документацию, описывающую, будут ли Core Data затем откатывать изменения для сохранения A.

Мне кажется странным, что граф объектов останется в несогласованном состоянии (т. Е. Обновлено одно хранилище) но несколько сложный и ресурсоемкий, чтобы полностью реализовать атомную экономию в нескольких магазинах. Было бы просто очень полезно разъяснить здесь, возможно, у кого-то, у кого больше опыта в системе!

ответ

5

Я, наконец, наткнулся на ответ сегодня в CoreDataErrors.h. Существует код ошибки:

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

Таким образом, кажется, что основные данные не будут пытаться откатить спасает от магазинов, которые действительно преуспевали. И действительно, не может обеспечить атомарность в нескольких магазинах. Справедливо!

1

Это звучит как нечто, что было бы нелегко получить экспериментальный ответ, воссоздав ваши условия - есть ли у вас время, чтобы воссоздать сценарий, который вы набросаете?

Я хотел бы сделать это следующим образом:

  1. создание двух sqllite магазинов и писать набор данных для каждого из файлов.
  2. закрытие магазинов
  3. удалить второй sqllite файл
  4. выписывать легко видеть работу на первом магазине (может быть лучше, чтобы сделать вставку в одну таблицу и удалить из другого). Объедините это с другой операцией во втором хранилище и который должен выйти из строя из-за недостающего файла 5. Проверить состояние первого хранилища.

Мое ощущение, что изменения в магазине A не будут откатываться назад, но я буду впечатлен любым другим ответом.

+0

Я еще не пробовал. Я несколько настороженно отношусь к тому, что экспериментальный результат является документированным поведением, поскольку любое изменение в поведении было бы довольно катастрофическим для того, что я планирую! Я надеялся, что кто-то может указать мне на клочок документации по этому вопросу, который я не смог найти в своих поисках. –

+1

Ну, я не могу найти никакой документации. Тогда я планировал бы наихудший сценарий и предполагал, что откат не будет работать над двумя хранилищами данных и не позволит вам каким-то образом обработать код. Вы всегда можете попробовать делать вставки в фиктивные таблицы перед началом большой транзакции, чтобы убедиться, что состояние магазинов в порядке. – Grouchal

+0

@Grouchal - Я не уверен, что тест, который вы предлагаете, будет работать. По умолчанию CoreData будет создавать второй магазин по мере необходимости (если файл был закрыт, как вы предлагаете). Если файл был открыт, файловая система unix отменила бы файл из файловой системы, но в стеке CoreData все равно будет доступ к несвязанному файлу, пока он не будет закрыт. – xyzzycoder

0

Один из вариантов достижения транзакций через несколько источников данных известен как «двухфазный фиксатор»." http://en.wikipedia.org/wiki/Two-phase_commit_protocol

Двухфазное фиксации системы обычно встречаются в развитии предприятия, иногда встроены в системах обработки транзакций http://en.wikipedia.org/wiki/Transaction_processing_monitor

, таких как Tuxedo http://en.wikipedia.org/wiki/Tuxedo_(software)

CoreData это на самом деле не предприятие объектно-реляционного и я не считаю, что он способен к двухфазным коммитам. Некоторые типы хранилищ, поддерживаемые CoreData, а не транзакционные или атомарные. Для поддержки двухфазного фиксации необходимо, чтобы каждый постоянный хранилище являлся как транзакцией nal и atomic.

Смежные вопросы