]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Don't leave connections in transaction after pool.check()
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Wed, 10 Nov 2021 01:21:37 +0000 (02:21 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Wed, 10 Nov 2021 02:00:52 +0000 (03:00 +0100)
Close #144.

psycopg_pool/psycopg_pool/pool.py
psycopg_pool/psycopg_pool/pool_async.py
tests/pool/test_pool.py
tests/pool/test_pool_async.py

index 27cc35fb774b35b2833fd8a9a1b632ed144b3e83..74dda9e7a56f13c5a890611fa7eb23b8de5afc41 100644 (file)
@@ -358,6 +358,8 @@ class ConnectionPool(BasePool[Connection[Any]]):
             conn = conns.pop()
             try:
                 conn.execute("SELECT 1")
+                if conn.pgconn.transaction_status == TransactionStatus.INTRANS:
+                    conn.rollback()
             except Exception:
                 self._stats[self._CONNECTIONS_LOST] += 1
                 logger.warning("discarding broken connection: %s", conn)
index ae161297812c66b5b61a83d3bf3d6e296885b985..f1da22240afd0a334a558d8bd4f67ca83177422d 100644 (file)
@@ -294,6 +294,8 @@ class AsyncConnectionPool(BasePool[AsyncConnection[Any]]):
             conn = conns.pop()
             try:
                 await conn.execute("SELECT 1")
+                if conn.pgconn.transaction_status == TransactionStatus.INTRANS:
+                    await conn.rollback()
             except Exception:
                 self._stats[self._CONNECTIONS_LOST] += 1
                 logger.warning("discarding broken connection: %s", conn)
index dfeca1d817aabb12d585f7495c226cb2849858d4..703bf70e0254b5f556c1393d38e9753e976b683e 100644 (file)
@@ -910,6 +910,14 @@ def test_check(dsn, caplog):
         assert pid not in pids2
 
 
+def test_check_idle(dsn):
+    with pool.ConnectionPool(dsn, min_size=2) as p:
+        p.wait(1.0)
+        p.check()
+        with p.connection() as conn:
+            assert conn.info.transaction_status == TransactionStatus.IDLE
+
+
 @pytest.mark.skipif(
     sys.version_info >= (3, 7), reason="async pool supported from Python 3.7"
 )
index a05fe82838caa0ea706f42383b150a91a0c34936..608c35e0cd26799e27532ff03421f5e769d3d3ce 100644 (file)
@@ -907,6 +907,14 @@ async def test_check(dsn, caplog):
         assert pid not in pids2
 
 
+async def test_check_idle(dsn):
+    async with pool.AsyncConnectionPool(dsn, min_size=2) as p:
+        await p.wait(1.0)
+        await p.check()
+        async with p.connection() as conn:
+            assert conn.info.transaction_status == TransactionStatus.IDLE
+
+
 @pytest.mark.slow
 @pytest.mark.timing
 async def test_stats_measures(dsn):