我有一个具有一对多关系和级联删除规则的对象。删除此对象会启动删除许多相关对象(30 000及更多)。当我在删除后保存上下文时,它会花费不允许的时间(几十秒,也许一分钟)。此外,当我在上下文尚未完成保存时尝试获取某些数据时 - 我得到一个锁。
该应用仅使用一个NSPrivateQueueConcurrencyType
的上下文。有没有办法在删除对象后保存上下文,并且能够同时获取数据?是否有任何技术有多个上下文甚至协调员?
答案 0 :(得分:1)
简短回答:启用WAL,批量保存,并尝试不同的上下文和/或持久性商店协调员。
Core Data中有不同级别的锁。上下文级别存在锁定。如果在多个地方使用上下文,并且一个地方使用上下文,则其他地方等待。有人甚至可能不称它为锁,而只是正常使用上下文。如果上下文是限制(传统)类型,则必须从一个线程或串行队列使用它。所以,连续。如果它在一个队列并发类型上,那些队列也是串行的,只是由Core Data为我们管理。
然后在持久性商店协调员级别上存在锁定。如果两个上下文使用相同的持久性存储协调器,并且一个上下文以需要持久性存储协调器工作的方式使用,则其他上下文将等待。从锁定的角度来看,这比只有一个上下文更有效,但是你需要在上下文之间来回合并数据。
然后锁定数据库文件本身。如果使用了多个持久性存储协调器,并且某些作业需要使用持久性存储,则另一个协调器及其所有上下文都在等待。但如果它不需要商店,他们就不会等待。这是避免锁定的最佳设计,但它也带来了成本。首先,您需要在上下文之间合并更改。但在大多数Core Data应用程序中,这实际上是很平常的事情。但其次,当有两个持久存储协调器时,您有两个独立的缓存。这有时会非常不方便。我甚至会说这是屁股的痛苦。
谈到SQLite,你可以启用WAL,让读者可以与作家同时工作。
Apple还建议您在需要保存大量数据时分批保存。
我个人推荐以下组合。
使用不同的上下文将允许您不锁定上下文级别。通过使用单个持久性存储协调器,您将从单个缓存中受益。通过启用WAL,您将减少文件级别的锁定。