有时,我使用^{
我注意到在一些地方,我在处理完数据库之后不会调用explicitcursor.close()
。到目前为止,这还没有导致任何错误或性能问题。我想知道如果不显式地关闭游标,可能会有什么问题,什么会出错?
据我所知,Django中的connection
和cursor
遵循“Python数据库API规范v2.0”(PEP-249)。根据它,只要调用__del__()
方法,cursor
就会自动关闭。我想问题也可能是:当它没有被调用时,是否有用例?
仅供参考,我使用的是Python2.7和Django1.6.5。
__del__
/.close()
:__del__
不能保证被调用__del__
中不调用cursor.close()(错误做法,但正确)一般在服务器连接上
大多数服务器都有一个空闲超时配置属性(我们称之为T)。如果连接空闲时间超过T秒,服务器将删除该连接。大多数服务器还具有设置工作线程池(W)大小的属性。如果您已经有W个连接到服务器,则在尝试新连接时可能会挂起。再想象一下,您没有显式关闭连接的选项。在这种情况下,必须将超时设置为足够小,以使工作池永远不会完全使用,这是您有多少并发连接的函数。
但是,如果您确实关闭了游标/连接(即使不等同于上面的[3],它们的行为也类似),那么您不必管理这些服务器配置属性,您的线程池只需足够大,就可以管理所有并发连接(可以选择偶尔等待新资源)。我见过一些服务器(如卡桑德拉的Titan)无法从线程池中的工作人员不足中恢复,因此整个服务器会一直停机直到重新启动。
TL/DR 如果您使用的是非常完善的库,比如
dano
提到的库,那么就不会有问题。如果您使用的是不太原始的库,那么如果您不调用.close()
,则可能会在服务器上阻塞获取工作线程,这取决于您的服务器配置和访问率。虽然通常可以依赖操作系统来释放资源,但关闭数据库连接之类的东西以确保在不再需要资源时释放资源始终是良好的卫生习惯,从数据库的角度来看,真正重要的是确保任何更改都是
commit()
edDjango的
cursor
类只是底层DB的cursor
的包装,因此保持cursor
打开的效果基本上与底层DB驱动程序相关。根据psycopg2(psycopg2是Django用于PostgreSQL数据库的数据库驱动程序)FAQ,它们的游标是轻量级的,但会缓存使用游标对象进行查询时返回的数据,这可能会浪费内存:
Django使用} documentation for ^{} 指出,在完成这些操作后,关闭服务器端光标非常重要:
MySQLdb
作为MySQL的后端,MySQL有几种不同类型的游标,包括一些实际将结果集存储在服务器端的游标。^{但是,这与Django无关,因为它使用由} method 只会删除对db连接的内部引用,并耗尽存储的结果集:
MySQLdb
提供的默认Cursor
类,该类在客户端存储结果。打开已使用的游标只会浪费存储结果集使用的内存,就像psycopg2
。光标上的^{从它们的源代码可以看出,Django使用的所有剩余后端(cx_oracle,sqlite3/pysqlite2)都遵循相同的模式;通过删除/重置存储的结果/对象引用来释放内存。sqlite3 docs甚至没有提到
Cursor
类有一个close方法,它只在包含的示例代码中偶尔使用。当对
cursor
对象调用__del__()
时,cursor
将被关闭,这是正确的,因此,如果要长期保持对cursor
的引用(例如,作为类的实例方法而保留的self.cursor
对象),则只需要显式关闭。相关问题 更多 >
编程相关推荐