我正在使用psycopg2作为我正在使用的樱桃应用程序和cli& phpgadmin手动处理一些操作。这是python代码:
#One connection per thread
cherrypy.thread_data.pgconn = psycopg2.connect("...")
...
#Later, an object is created by a thread :
class dbobj(object):
def __init__(self):
self.connection=cherrypy.thread_data.pgconn
self.curs=self.connection.cursor(cursor_factory=psycopg2.extras.DictCursor)
...
#Then,
try:
blabla
self.curs.execute(...)
self.connection.commit()
except:
self.connection.rollback()
lalala
...
#Finally, the destructor is called :
def __del__(self):
self.curs.close()
我遇到了psycopg或postgres的问题(尽管我认为后者更有可能)。在发出一些问题后,我的连接就丢失了。同样,phpgadmin -usually-也会被删除;在多次提出请求后,它会提示我重新连接。只有CLI保持持久性。
问题是,这些都是随机发生的,我甚至无法追查原因。我可以在几页请求后被锁定,或者在请求数百页之后从未真正遇到过任何问题。在终止应用程序后,我在postgres日志中发现的唯一错误是:
...
LOG: unexpected EOF on client connection
LOG: could not send data to client: Broken pipe
LOG: unexpected EOF on client connection
...
我想在每次创建新的dbobj实例时创建一个新连接,但我绝对不想这样做。
另外,我已经读过,除非提交所有事务,否则可能会遇到类似的问题:我对每个INSERT / UPDATE查询都使用try / except块,但是我从来没有将它用于SELECT查询,也不想使用它写更多的样板代码(顺便说一句,他们需要提交吗?)。即使是这样,为什么phpgadmin会关闭?
<。> .conf文件中的max_connections设置为100,所以我认为这也不是原因。一个樱桃工人只有10个线程。有没有人知道我应该先看哪儿?
答案 0 :(得分:1)
Psycopg2需要在每次事务(包括SELECT查询)之后提交或回滚,或者它会离开连接&#34; IDLE IN TRANSACTION&#34;。现在这是文档中的警告:
警告:默认情况下,任何查询执行,包括一个简单的SELECT都将启动一个事务:对于长时间运行的程序,如果不采取进一步的操作,会话将保持“在事务中空闲”,这是一个不合需要的条件,原因有几个(会话持有锁,表膨胀......)。对于长期存在的脚本,要么确保尽快终止事务,要么使用自动提交连接。
答案 1 :(得分:0)
要确切了解您填充和访问cherrypy.thread_data
的位置有点困难。我建议调查psycopg2.pool.ThreadedConnectionPool
,而不是试图自己将一个conn绑定到每个线程。
答案 2 :(得分:0)
即使我不知道为什么成功的SELECT
查询会阻止连接,但几乎每个不需要与另一个查询一起工作的查询都会解决问题后,.commit()
会出现问题