fix: connection pool exhaustion + cross_ref column name

- tenant_db.py: add rollback() before returning conn to pool to prevent
  'idle in transaction (aborted)' state that exhausts the pool
- tenant_db.py: increase pool maxconn from 10 to 20 for better concurrency
- inventory_vehicle_compat.py: fix column name cross_ref_number ->
  cross_reference_number to match actual schema
This commit is contained in:
2026-05-01 02:25:58 +00:00
parent 2b418701b6
commit 0e549e7746
2 changed files with 13 additions and 4 deletions

View File

@@ -19,7 +19,7 @@ def auto_match_vehicle_compatibility(master_conn, tenant_conn, inventory_id, par
Searches: Searches:
1. parts.oem_part_number (exact, case-insensitive, spaces stripped) 1. parts.oem_part_number (exact, case-insensitive, spaces stripped)
2. aftermarket_parts.part_number 2. aftermarket_parts.part_number
3. part_cross_references.cross_ref_number 3. part_cross_references.cross_reference_number
Returns: Returns:
dict: {'matched': bool, 'matches': [...], 'myes': [...]} dict: {'matched': bool, 'matches': [...], 'myes': [...]}
@@ -46,7 +46,7 @@ def auto_match_vehicle_compatibility(master_conn, tenant_conn, inventory_id, par
if not oem_ids: if not oem_ids:
cur.execute(""" cur.execute("""
SELECT DISTINCT part_id FROM part_cross_references SELECT DISTINCT part_id FROM part_cross_references
WHERE REPLACE(UPPER(cross_ref_number), ' ', '') = %s WHERE REPLACE(UPPER(cross_reference_number), ' ', '') = %s
""", (clean_pn,)) """, (clean_pn,))
oem_ids = [r[0] for r in cur.fetchall() if r[0]] oem_ids = [r[0] for r in cur.fetchall() if r[0]]

View File

@@ -21,7 +21,7 @@ def _get_master_pool():
global _master_pool global _master_pool
if _master_pool is None: if _master_pool is None:
_master_pool = pool.ThreadedConnectionPool( _master_pool = pool.ThreadedConnectionPool(
minconn=2, maxconn=10, dsn=MASTER_DB_URL minconn=2, maxconn=20, dsn=MASTER_DB_URL
) )
return _master_pool return _master_pool
@@ -32,7 +32,7 @@ def _get_tenant_pool(db_name):
if db_name not in _tenant_pools: if db_name not in _tenant_pools:
dsn = TENANT_DB_URL_TEMPLATE.format(db_name=db_name) dsn = TENANT_DB_URL_TEMPLATE.format(db_name=db_name)
_tenant_pools[db_name] = pool.ThreadedConnectionPool( _tenant_pools[db_name] = pool.ThreadedConnectionPool(
minconn=2, maxconn=10, dsn=dsn minconn=2, maxconn=20, dsn=dsn
) )
return _tenant_pools[db_name] return _tenant_pools[db_name]
@@ -52,6 +52,15 @@ class _PooledConnection:
def close(self): def close(self):
try: try:
# Rollback any aborted transaction before returning to pool.
# Without this, failed transactions leave connections in
# 'idle in transaction (aborted)' state, eventually exhausting
# the pool.
if self._conn:
try:
self._conn.rollback()
except Exception:
pass
self._pool.putconn(self._conn) self._pool.putconn(self._conn)
except Exception: except Exception:
# If pool is already closed, fall back to real close # If pool is already closed, fall back to real close