重い負荷がかかると、ピラミッド Web アプリが py-postgresql 例外をスローすることがわかりpostgresql.exceptions.ProtocolError
ました。一部の検索で、py-postgresql はスレッドセーフではなく、1 つの接続を複数のスレッドで同時に使用できないことが明らかになりました。
ある種のプーリング メカニズムを作成しようとしましたが、それでも 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
このコードは多くのスレッドで同時に実行できますが、ロックのために 1 つの接続で2 つのスレッドを同時に実行することはできないと思います。
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 の「スレッドの安全性」の性質を誤解したのでしょうか? 私を助けてください!