【问题标题】:Core Data store atomicity with multiple stores具有多个存储的核心数据存储原子性
【发布时间】:2010-11-02 22:28:24
【问题描述】:

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

如果存储 A 正确保存,但存储 B 由于某种原因无法保存怎么办?(例如,磁盘上的文件被删除,或者权限使其只读,诸如此类)。我找不到任何文档详细说明 Core Data 是否会将更改回滚到存储 A。

在我看来,对象图会处于不一致的状态(即一个存储已更新,一个未更新)对我来说似乎很奇怪,但在多个存储之间执行完全原子保存有点棘手且资源密集。真的很想在这里澄清一下,也许来自对系统有更多经验的人!

【问题讨论】:

    标签: cocoa macos core-data


    【解决方案1】:

    我今天终于在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 似乎不会尝试从成功的存储中回滚保存。而且确实不能提供跨多个商店的原子性。够公平的!

    【讨论】:

      【解决方案2】:

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

      我会这样做:

      1. 创建两个 sqllite 存储并将一组数据写入每个文件。
      2. 关闭商店
      3. 删除第二个sqllite文件
      4. 在第一个存储上编写一个易于查看的操作(最好是插入一个表并从另一个表中删除)。将此与第二个商店上的另一个操作结合起来,由于缺少文件,该操作应该会失败 5.查看第一家店铺的状态。

      我感觉存储 A 的更改不会回滚 - 但任何其他答案都会给我留下深刻印象。

      【讨论】:

      • 我还没试过这个。我有点担心将实验结果视为记录的行为,因为行为的任何变化都会对我的计划造成灾难性的后果!我希望有人能指出我在搜索中未能找到的有关这件事的一些文档。
      • 好吧,我找不到任何文档。然后我会为最坏的情况做计划,并假设回滚不会在两个数据存储上起作用,并确保您的代码可以以某种方式处理这个问题。在开始大事务之前,您总是可以尝试对虚拟表进行插入操作,以确保商店的状态正常。
      • @Grouchal - 我不确定您提出的测试是否有效。默认情况下,CoreData 将根据需要创建第二个存储(如果文件按照您的建议关闭)。如果文件是打开的,unix 文件系统会从文件系统中取消链接文件,但 CoreData 堆栈仍然可以访问未链接的文件,直到它被关闭。
      【解决方案3】:

      实现跨多个数据源的事务的一种选择称为“两阶段提交”。 http://en.wikipedia.org/wiki/Two-phase_commit_protocol

      两阶段提交系统在企业开发中很常见,有时嵌入在事务处理系统中 http://en.wikipedia.org/wiki/Transaction_processing_monitor

      比如燕尾服 http://en.wikipedia.org/wiki/Tuxedo_(software)

      CoreData 并不是真正的企业对象关系映射工具,而且我不相信它能够进行两阶段提交。 CoreData 支持的一些存储类型,而不是事务性或原子性的。为了支持两阶段提交,需要每个持久存储既是事务性的又是原子的。

      【讨论】:

        猜你喜欢
        • 2023-03-07
        • 2015-02-03
        • 1970-01-01
        • 2011-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多