我们使用一个与PostgreSQL数据库保持连接的对象,并创建新的游标来提供请求。我观察到奇怪的行为:即使在读取响应并且光标关闭时,请求仍然挂在数据库中,阻止更新表等等。
当连接关闭时,它会消失。
我了解ORM框架,也许最终会使用其中一个,但我只是想了解这里发生了什么。为什么请求仍在那里?
这是python代码:
import psycopg2
def main():
conn = psycopg2.connect("dbname=tmpdb password=1 host=localhost")
cur = conn.cursor()
cur.execute("SELECT 1;")
items = cur.fetchall()
cur.close()
#uncommenting the following line solves the problem
#conn.close()
print items
while True:
pass
main()
以下是启动代码的方法:
>python test_loop.py
[(1,)]
以下是观察悬挂请求的方法:
tmpdb=# SELECT datname,usename,pid,client_addr,waiting,query_start,query FROM pg_stat_activity ;
datname | usename | pid | client_addr | waiting | query_start | query
---------+----------+-------+-------------+---------+-------------------------------+------------------------------------------------------------------------------------------
tmpdb | savenkov | 530 | ::1 | f | 2013-08-12 13:56:32.652996+00 | SELECT 1;
tmpdb | savenkov | 88351 | | f | 2013-08-12 13:56:35.331442+00 | SELECT datname,usename,pid,client_addr,waiting,query_start,query FROM pg_stat_activity ;
(2 rows)
答案 0 :(得分:1)
为什么你认为它是封锁的?
创建表格
create table t (i integer);
现在运行它:
import psycopg2
def main():
conn = psycopg2.connect("dbname=cpn")
cur = conn.cursor()
cur.execute("SELECT i from t;")
items = cur.fetchall()
print items
raw_input('Enter to insert')
cur.execute("insert into t (i) values (1) returning i;")
items = cur.fetchall()
conn.commit()
cur.execute("SELECT i from t;")
items = cur.fetchall()
print items
raw_input('Enter to update')
cur.execute("update t set i = 2 returning i")
items = cur.fetchall()
conn.commit()
cur.execute("SELECT i from t;")
items = cur.fetchall()
print items
cur.close()
while True:
pass
main()
请注意,您需要connection.comit()
才能提交。
据说不要做连接管理。而是使用像Pgbouncer这样的连接池。它将为您免除大量复杂性和挫败感。
如果应用程序在与db相同的机器上运行,那么甚至不用打扰。只需要经常关闭连接。如果两者都在快速内联网中,除非存在大量查询,否则连接池的复杂性也不值得。