gpt4 book ai didi

ios - 原子删除数据库实体和文件

转载 作者:行者123 更新时间:2023-11-30 12:14:02 25 4
gpt4 key购买 nike

假设我们有一个核心数据实体Image,它有一个属性url,用于存储实际图像文件的文件系统 URL。我们可以像这样实现删除功能:

func deleteImage(_ image: Image) {
do {
let url = image.url
delete(image)
try save()
try FileManager.default.removeItem(at: url)
} catch {
rollback()
}
}
  • 如果save()removeItem(at:)都成功,则操作成功。
  • 如果save()失败,数据库将回滚到原始状态。
  • 但是,如果 save() 成功但 removeItem(at:) 失败,孤立文件将保留在文件系统中。

有没有办法使 deleteImage() 原子化,而不涉及定期检查和删除孤立文件的单独进程?

-

可以使用isDeletableFile(atPath:),但仍然不是 100% 可靠。

func isDeletableFile(atPath path: String) -> Bool

Attempting to predicate behavior based on the current state of the file system or a particular file on the file system is not recommended. Doing so can cause odd behavior or race conditions. It's far better to attempt an operation (such as loading a file or creating a directory), check for errors, and handle those errors gracefully than it is to try to figure out ahead of time whether the operation will succeed.

最佳答案

真正的原子删除很难实现,但是如果稍微改变一下语句的顺序,就可以大大提高代码的稳定性:

  1. 删除数据库中的图像。
  2. 如果成功,请将文件移动到临时文件夹。
  3. 如果成功,则提交。
  4. 成功后,删除临时文件夹中的文件,否则将文件移回其原始位置。

如果操作 1 或 2 不成功则回滚。 4 的第一部分并不是真正必要的,您可以或应该在某些时候清理临时文件夹(例如程序启动、从后台返回)。在极少数情况下,4 的 else 部分可能会失败,从而导致状态不一致。

更复杂的更改可能会导致原子删除。您不会删除对象,而只是将它们标记为已删除。第二步首先删除文件(如果存在),然后删除实体。您可以在每次删除后立即应用第二步,也可以在某些其他时间点应用第二步。此解决方案的缺点是它的复杂性,因为您必须在每次数据访问时考虑已删除的对象。

关于ios - 原子删除数据库实体和文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45646238/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com