Core Data 可以在 iOS 上提供什么(如果有)ACID 保证?

发布于 2024-11-19 08:44:07 字数 301 浏览 4 评论 0原文

我正在开发一个应用程序,我需要以可靠的方式保存数据,即即使面对应用程序崩溃和退出等情况,更新也需要全部或全部保存。

但是我找不到太多关于核心数据能够支持的恢复能力水平,从环顾四周来看,核心数据损坏似乎是有可能的。这是正确的还是核心数据能够提供支持可靠所需的高低级别 ACID 属性数据存储?

请具体说明哪些 API 提供了这些保证 - 例如,即使在保存期间发生崩溃(可能在另一个线程上),保存是否保证提交所有更新或不提交任何更新?

I'm working on an app where I need to persist data in a reliable manner, i.e. updates need to be persisted all-or-nothing even in the face of application crashes and quits etc.

However I can't find much information on the level of resilience Core Data is able to support and from looking around it seems that Core Data corruption is a possibility. Is this correct or is Core Data able to provide the high and low level ACID properties needed to support reliable data storage?

Please be specific as to which APIs give these guarantees - for example is a save guaranteed to commit all updates or none, even if a crash occurs (possibly on another thread) during the save?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

山有枢 2024-11-26 08:44:07

ACID 仅适用于数据库,而 Core Data 不是数据库 API,因此 ACID 标准并不真正适用于 Core Data。 ACID 充其量仅适用于使用 SQLite 持久存储的情况,不适用于二进制、xml、内存中或自定义原子存储。

NSManagedObjectContext 确实强制执行前三个 ACID 组件:原子性、一致性和隔离性。原则上你可以打开SQLite的日志功能并获得Durability。

ACID 被认为是多用户大型数据库的理论标准。原子性、一致性和隔离性都是为了防止多个并发用户事务互相干扰而破坏数据库。持久性实际上仅适用于实际上无法备份的系统。

相比之下,核心数据是用于实现模型-视图-控制器设计应用程序的模型层的 API。它的持久性功能只是可选的。它不支持多个用户,而仅支持同一应用程序的多个子进程。

没有任何系统可以在硬件故障时完美保证数据的完整性。您充其量可以保证可以恢复到数据的早期版本,但在进行更改时无法防止硬件故障。

话虽如此,Core Data 非常强大。我见过一些持久性存储损坏的案例,而且通常只在极端条件下发生。我认为目前可用于桌面和移动平台的任何其他系统都不会更可靠。

更新:

请具体说明哪些 API
提供这些保证 - 例如
一次保存保证提交所有
更新或不更新,即使崩溃
发生(可能在另一个线程上)
保存期间?...的种类
我指的失败是崩溃
在应用程序内或退出应用程序
- 在这种情况下,最好只获取最后一笔交易
受到影响(即损失,最坏的情况),但我
不知道如何表达这一点
核心数据

这里有两个方面值得关注,持久存储写入磁盘的操作以及托管对象上下文维护对象图完整性和保存图的操作。

对于 SQLite 存储,SQLite 本身符合 ACID:

事务数据库是其中之一
所有更改和查询都会出现
原子的、一致的、孤立的、
耐用(酸性)。 SQLite 实现
可序列化的事务是
原子的、一致的、孤立的和
持久的,即使交易是
因程序崩溃而中断,
操作系统崩溃,或电源
计算机故障。

对于作为单一文件写出的其他存储,Core Data 将使用 安全写入确保现有的正常文件不会被损坏的文件覆盖的方法

在对象图的较高抽象级别,托管对象上下文在写入存储之前执行验证,如果发生任何验证错误,则将拒绝整个写入尝试。(链接待定。)此行为是对象图所必需的。

对象图是内存中相关活动对象的集合。与数据仅在字段中编码的过程数据库不同,对象之间的关系对重要数据进行编码。因此,整个图必须一步验证,然后一步保存。 (当然,在使用 sqlite 存储的幕后,将会有符合 ACID 的程序步骤,但在达到此级别之前会发生对象图的验证。)

例如,您有一个数据模型来建模/模拟文件系统。它有两个实体:FolderFile。每个 File 对象与单个 Folder 对象都具有必需的关系,因为每个实际文件始终位于文件夹内。但是,您插入的文件对象没有文件夹。当上下文验证对象图进行保存时,它将拒绝整个图,因为该图对于不在文件夹内的文件对象来说是无意义的。

ACID only applies to databases and Core Data isn't a database API so the ACID standard doesn't really apply to Core Data. At best ACID applies only in the case of the use of a SQLite persistent store and does not apply to binary, xml, in-mmemory or custom atomic stores.

The NSManagedObjectContext do enforce the first three ACID components: Atomicity, Consistency and Isolation. You can in principle turn on SQLite's logging function and get Durability.

ACID was conceived as a theoretical standard for multiuser, big-iron databases. Atomicity, Consistency and Isolation are all intended to keep multiple simultaneous user transactions from corrupting the database by stepping on each other. Durability really applies only to a system that cannot be practically backed up otherwise.

Core Data, by contrast, is an API for implementing the model layer of Model-View-Controller design application. It's persistence functions are merely optional. It does not support multiple users but merely multiple subprocesses of the same app.

There is no system which can perfectly guarantee data integrity in the face of a hardware failure. At best you can guarantee that you can revert to an earlier version of the data but you cannot protect against hardware failure while you are making changes.

Having said all that, Core Data is very robust. I have seen a literal handful of cases of corrupt persistent stores and then usually only under extreme conditions. I don't think any other system currently available for desktop and mobile platforms is more reliable.

Update:

Please be specific as to which APIs
give these guarantees - for example is
a save guaranteed to commit all
updates or none, even if a crash
occurs (possibly on another thread)
during the save?... The kinds of
failures I am referring to are crashes
within the app or quitting of the app
- in this case it is desirable that only the last transaction gets
affected (i.e. lost, at worst), but I
don't see how to express this with
Core Data

There are two areas of concern here, the operations of the persistent store writing to disk and the operations of the managed object context in maintaining object graph integrity and saving the graph.

For the SQLite store, SQLite itself is ACID compliant:

A transactional database is one in
which all changes and queries appear
to be Atomic, Consistent, Isolated,
and Durable (ACID). SQLite implements
serializable transactions that are
atomic, consistent, isolated, and
durable, even if the transaction is
interrupted by a program crash, an
operating system crash, or a power
failure to the computer.

For the other stores, which are written out as unitary files, Core Data will use safe write methods that insure that an existing good file will not be overwritten by a corrupted file.

At the higher abstraction level of the object graph, the managed object context performs validations before writing to the store and will reject the entire write attempt if any validation errors occur.(Link Pending.) This behavior is necessitated by the object graph.

An object graph is a collection of related live objects in memory. Unlike a procedural database, where data is only encoded in fields, the relationships between the objects encodes vital data. Therefore, the entire graph must be validated in step and then saved in one step. (Of course, behind the scenes using an sqlite store, there will be procedural ACID compliant steps but validation of the object graph occurs before this level is reached.)

E.g. You have a data model to model/simulate a file system. It has two entities: Folder and File. Each File object has a required relationship with a single Folder object because each real-world file is always inside a folder. However, you insert a file object that has no folder. When the context validates the object graph for a save, it will reject the entire graph because the graph is nonsensical with a file object that is not inside a folder.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文