核心数据和数据完整性:读操作与写操作。如何保护?

Posted

技术标签:

【中文标题】核心数据和数据完整性:读操作与写操作。如何保护?【英文标题】:Core data and data integrity: read operations vs write operations. How to protect? 【发布时间】:2013-12-28 07:40:03 【问题描述】:

我有一个我认为很简单的任务。

我有一个名为[self getPerson] 的方法,它从Web 服务对Person 发出简单的GET 请求,该请求返回一些JSON,然后将JSON 转换为NSManagedObject。检查现有的相同Person NSManagedObject,如果没有找到,则将Person 保存到核心数据中。没问题。

但是,如果我连续两次启动此方法,我会得到两个 Person NSMangedObjects 持久化到核心数据中。例如:

[self getPerson];
[self getPerson];  ---> yields duplicate `Person` objects saved in core data, no good.

如何确保只有一个 Person 对象保存在 Core Data 中(不允许重复)?

我知道问题所在,只是不知道如何解决。问题是我需要一笔交易。当 [self getPerson] 第一次触发时,该方法检查已经存在的相同 Person 对象,没有找到,并将新的 Person 保存到核心数据中。这是对的。当我第二次触发[self getPerson] 时,该方法会检查一个已经存在的Person 对象,但没有看到一个对象,然后会保留另一个Person 对象。这是不正确的。我想让第二次、第三次和第四次到第 1000 次,检查现有的 Person 对象只会在 managedObjectContext saveoperation 完成后发生。现在检查现有对象的速度非常快(在保存完成之前)。

我需要串行队列吗?如果是这样,这应该是dispatch_async 还是dispatch_sync?我什至玩过尝试使用performSelectorWithDelay 技巧的想法。

【问题讨论】:

【参考方案1】:

一旦您创建了对象,无论您调用 save,它都将存在于数据库中。因此,如果已存在托管对象,则不应创建托管对象。目前尚不完全清楚您的代码逻辑是什么,但根据您的描述,您说您将 JSON 转换为托管对象,然后检查是否存在相同的现有对象,如果找不到则保存。好吧,当您创建托管对象时,您已经创建了它,因此检查是否存在相同的对象为时已晚。保存不会创建对象,如果尚未保存,它只是将其保存到存储中。

因此首先检查是否存在具有 JSON 中属性的人员对象,如果不存在则创建托管对象。

【讨论】:

【参考方案2】:

好吧,在这种情况下,串行队列将确保以正确的方式执行操作。

根据您的问题,也许我遗漏了一些东西,我无法理解 getPerson 方法是否负责获取和保存数据。如果没有,你应该这样做。

无论如何,如果您使用 JSON 并且您从服务器检索到的人具有唯一标识符,您应该使用它来查询 Core Data 并验证它是否存在。正确的做法是实现Implementing Find-or-Create Efficiently。

一个简单的问题。两次拨打getPerson 有什么理由吗?您不能使用标志(或瞬态属性)来阻止它吗?只是简单的想法。

【讨论】:

以上是关于核心数据和数据完整性:读操作与写操作。如何保护?的主要内容,如果未能解决你的问题,请参考以下文章

并发操作会带来哪些数据不一致性

oracle锁

第三周-第06章节-Python3.5-文件读与写详解

CPU处于保护模式时如何读/写硬盘?

使用ethers.js执行读函数与写函数

LINUX安全