3

我发现在重负载下,我的金字塔网络应用程序会抛出 py-postgresql 异常,例如postgresql.exceptions.ProtocolError. 一些搜索显示,py-postgresql 不是线程安全的,一个连接不能被多个线程同时使用。

我试图建立某种池机制,但我仍然得到 ProtocolErrors :(

我究竟做错了什么?

首先,我创建多个连接对象:

    for x in range(num_db_connections):
        self.pool.append(Connection(conn_string,x))

池中的每个对象都包含db_lock = threading.Lock()一个与数据库的连接self.conn = postgresql.open( conn_string )

然后我尝试获取连接上的锁定并使用它做一些工作。这段代码可以由多个线程同时执行,但我认为work由于锁定,没有两个线程可以同时在一个连接上运行。

    time_start = time.time()
    while time.time() - time_start < self.max_db_lock_wait_time:
        for conn in self.pool:
            acquired = conn.db_lock.acquire(False)
            if acquired:
                try:
                        lst = conn.work()
                finally:
                    conn.db_lock.release()
                return lst
        time.sleep(0.05)
    raise Exception('Could not get connection lock in time')

也许我的代码有缺陷,或者我误解了 py-postgresql 的“线程不安全”的性质?请帮我!

4

1 回答 1

2

你确定你没有在你的锁之外使用游标对象吗?

只是一个建议:不要使用 time.sleep() 和“尝试”锁定,而是使用队列将连接对象从池中弹出/推送到池中。那已经是线程安全的,并且它有一个超时参数。更有效。特别是如果您有很多线程而只有几个连接。(当您需要运行 100 000 个查询时,这些微小的睡眠指令会加起来。所有这些指令都会增加您的响应时间。)

于 2012-09-27T19:32:50.773 回答