-->

ZODB:到了那里transaction.savepoint写入数据?(ZODB: To where

2019-10-18 21:03发布

据ZODB文件 :

保存点允许数据管理器保存工作,它的存储没有提交完整的事务。”“保存点也对,否则将被用来保持交易的全状态可用内存有用。

按照很有启发性的文章当在ZODB提交数据 (马亭皮特斯):

......整个交易在那里,你可以要求数据被暂时存储在磁盘中的一个点。 [...]
有一件事保存点呢,就是呼吁ZODB缓存的垃圾收集,这意味着当前未使用任何数据从内存中删除。

问题是,我需要很多的项目存储在一个事务中,这样的事情:

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

我kindof预计transaction.savepoint工作方法一样bsddb3.db.Db.sync 。 当Db.sync()被调用,数据库被刷新,可看到它。 但是,当一个保存点设置,显然既不是数据库也不是tmp文件增长或大小,直到变化transaction.commit()

我真的很困惑:

  • 当保存点设置什么是实际发生的?

  • 它是如何从commiting /冲洗数据库有什么不同?

  • 如果“数据被暂时存储在磁盘上”,到哪里保存点写入数据?

  • 我能指望保存点到字面意思是“无记忆”?

Answer 1:

用于保存点原,主要用途是能够回滚事务的一部分

假设你想接受大量的日志条目,但需要分批进入数据库来处理这些:

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数据库,并最终完成交易。



Answer 2:

保存点的主要用途,以释放内存和从内存中存储的交易相关数据到磁盘 - 尤其是大额交易和大量修改的数据。



文章来源: ZODB: To where transaction.savepoint writes data?