gpt4 book ai didi

python - ZODB:transaction.savepoint 向哪里写入数据?

转载 作者:太空宇宙 更新时间:2023-11-04 07:41:25 25 4
gpt4 key购买 nike

根据 ZODB documentation :

A savepoint allows a data manager to save work to its storage without committing the full transaction." "Savepoints are also useful to free memory that would otherwise be used to keep the whole state of the transaction.

根据很有启发性的文章When to commit data in ZODB (马丁·彼得斯):

... a point during the whole transaction where you can ask for data to be temporarily stored on disk. [...]
One thing a savepoint does, is call for a garbage collection of the ZODB caches, which means that any data not currently in use is removed from memory.

问题是,我需要在一次交易中存储很多项目,如下所示:

for i, item in enumerate(aLotOfItems):
database[i]=item
if i % 10000 ==0:
transaction.savepoint(True)
transaction.commit()

我有点希望 transaction.savepoint 以与 bsddb3.db.Db.sync 相同的方式工作。当 Db.sync() 被调用时,数据库被刷新,你可以观察到。但是,当设置保存点时,显然数据库和 tmp 文件都不会增长或改变大小,直到 transaction.commit()

我真的很困惑:

  • 设置保存点后实际发生了什么?

  • 它与提交/刷新数据库有何不同?

  • 如果“数据暂存在磁盘”,保存点将数据写到哪里?

  • 我可以指望保存点真正意义上的“释放内存”吗?

最佳答案

保存点最初的主要用途是能够回滚事务的部分

假设您想接受大量的日志条目,但需要将它们分批处理到数据库中:

for batch in per_batch(log_entries):
sp = transaction.savepoint()
try:
process_batch(batch)
except BatchFailedException:
sp.rollback()
transaction.commit()
raise

现在事务已经提交,除了最后一批已经回滚。

这是使用保存点的最初原因。设置保存点具有触发 ZODB 缓存垃圾收集运行的副作用。

ZODB 保存最近访问过的对象的缓存。这包括在当前交易期间实际上没有改变的对象;您只是从数据库中检索它们,使用它们的数据,然后停止直接引用它们。 ZODB 存储一个对象图;一个对象引用其他对象,而其他对象又引用其他对象。这些对象中的每一个,如果它们继承自 Persistent 基类,都是单独的 ZODB 记录。当你遍历图时,这些对象都被加载到内存中。

如果它们没有改变,GC 运行将再次从内存中清除它们。再次遍历对象图会将它们再次加载到内存中,但在保存点期间清除它们可以节省内存。

保存点数据本身存储在磁盘上的 TmpStorage 文件中,在您的 TEMP 目录中。这使用 tempfile.TemporaryFile()对象,出于安全原因在未链接状态下创建;该文件存在,但目录条目在创建时立即被清除。因此,您无法从 ZODB 进程外部查看此文件。

完整提交会将数据移动到实际的 ZODB 数据库中并完成事务。

关于python - ZODB:transaction.savepoint 向哪里写入数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19710941/

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