核心数据存储多个存储的原子性

时间:2009-06-15 05:36:29

标签: cocoa macos core-data

核心数据允许您将多个持久性存储添加到单个NSPersistentStoreCoordinator(每个具有不同的配置)名称,从而将它们组合在一个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
  3. 如果商店A保存正确,但商店B由于某种原因无法保存怎么办?(例如,磁盘上的文件被删除,或者权限只读,那种事情)。我找不到任何详细说明Core Data是否会将更改回滚到商店A的文档。

    对我来说,对象图将保持不一致状态(即一个商店更新,一个商店没有更新),这似乎很奇怪,但在多个商店中执行完全原子保存时有点棘手和资源密集。我真的希望在这里做一些澄清,也许来自对系统有更多经验的人!

3 个答案:

答案 0 :(得分:5)

我终于在CoreDataErrors.h偶然发现了答案。有一个错误代码:

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

因此,似乎Core Data不会尝试从成功的商店中回滚保存。并且确实不能跨多个商店提供原子性。足够公平!

答案 1 :(得分:1)

这听起来像通过重新创建条件来获得实验答案并不难 - 你有时间重新创建你勾勒出的场景吗?

我会这样做:

  1. 创建两个sqllite存储并将一组数据写入每个文件。
  2. 关闭商店
  3. 删除第二个sqllite文件
  4. 在第一个商店中写出一个易于查看的操作(可能最好插入一个表并从另一个表中删除)。将此与第二个存储上的另一个操作相结合,由于缺少文件,该操作将失败 5.检查第一家商店的状态。
  5. 我觉得存储A的更改不会被回滚 - 但任何其他答案都会让我印象深刻。

答案 2 :(得分: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支持的一些商店类型,而不是事务或原子。为了支持两阶段提交,需要每个持久存储都是事务性和原子性的。