我应该最大程度地减少小马orm中db_session的使用吗?db_session的目的是什么



我想知道,我是否应该最大程度地减少db_session的使用?让我们考虑以下两个等效示例:

a)

def do_stuff():
    with db_session:
        task = orm.make_proxy(Task.select().first())
        task.mark_started()
    ...
    this_function_might_take_a_long_time(task)
    ...
    with db_session:
        task.mark_done()

b)

@db_session
def do_stuff():
    task = Task.select().first()
    task.mark_started()
    commit()
    ...
    this_function_might_take_a_long_time(task)
    ...
    task.mark_done()

通过阅读文档,我可以说小马不鼓励微管理DB_Sessions

With this code each of view function you will define will be wrapped with db_session so you should not care about them.

但是,这里这表明可能有打开它的成本(编辑:没有,请阅读答案)

Before sending the first query, Pony gets a database connection from the connection pool.

我是否正确地说B之外的任何东西都是过早的优化,并且仅在有限的DB连接计数方案中考虑A?

小马作者亚历山大·科兹洛夫斯基(Alexander Kozlovsky)@MetapRogrammer在官方的小马电报聊天中回答了这一点。


db_session的目的是管理三件事:

数据库连接

小马会与每个线程分开连接。如果过程不使用线程,则只会使用一个连接。当DB_Session结束时,它将返回连接到连接池。这意味着连接保持开放,并保留未来的用法。下一个db_session将使用相同的连接。因此,关于计算用法,单个db_session和几个顺序db_sessions

之间没有区别

交易状态

db_session结束时,它执行隐式提交。隐式和显式提交之间没有区别,因此,如果您对手动commit()调用单个db_session与几个顺序db_sessions相同。但是,如果您不使用explicit commit(),则长db_session可以容纳数据库锁定,并防止其他进程与数据库或特定表一起使用,直到执行提交

加载对象的内存中缓存

单个db_session和几个顺序db_sessions之间的主要区别在于管理从数据库加载的对象的内存中缓存。每个db_session都有单独的缓存。缓存内部的对象与关系交联。如果您加载了一系列OD课程,学生和小组对象,则它们都通过关系属性相互联系。因此,不可能将某些对象从缓存中卸载并保留其余的对象。垃圾收集器不能仅从缓存中收集一些对象,因为它们都用圆形引用指向彼此。因此,只有在完成DB_Session完成后,可以将缓存删除。因此,如果您有一个长期存在的db_session,那么直到最后才能免费记忆。但是几个较小的db_session可能需要多次从数据库中加载相同的对象。因此,有记忆/性能权衡

P.S。即使完成DB_Session,连接仍将保持连接,直到程序结束或显式db.disconnect()呼叫。小马只有当DB_Session内部的某些数据库异常导致回滚时隐含关闭连接。

最新更新