DB 가 원격이라 질의 하나가 곧 왕복 12ms 임. 서로 기다릴 이유가 없는 읽기를 한 커넥션에서 순차로 내면 그 왕복이 그대로 더해짐. - config_db.run_with_connection: 저장소 함수를 자기 커넥션으로 돌려 gather 로 묶을 수 있게 하는 공용 헬퍼. 정의를 한 곳에 둠(drainage_context 의 _query 는 이 함수를 가리키는 이름으로 정리). 머리에 경고 적음 — 순서가 필요한 쓰기는 이걸로 묶으면 트랜잭션이 깨짐. - B04_PreProcess_Router_Watershed._prepare: 저장경로·좌표계·지표면확정값 세 건을 gather 로. 약 24ms 절약. common_util_auth_repository.py:318(decide_join_request)은 FOR UPDATE + 순서 있는 UPDATE 라 묶지 않음 — 읽기 블록만 대상. 자체검증 — 관 드래그 왕복 305 -> 259ms(최소 193), 관 11 · 유역 11 로 값 동일. 전체 484 통과. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
77 lines
2.4 KiB
Python
77 lines
2.4 KiB
Python
"""
|
|
config_db.py
|
|
데이터베이스 연결 설정 (MariaDB + aiomysql)
|
|
|
|
비동기 연결 풀 생성 및 관리.
|
|
"""
|
|
|
|
from collections.abc import Callable
|
|
from typing import Any, Optional
|
|
|
|
import aiomysql
|
|
|
|
from .config_system import (
|
|
DB_HOST,
|
|
DB_NAME,
|
|
DB_PASSWORD,
|
|
DB_POOL_MAX,
|
|
DB_POOL_MIN,
|
|
DB_PORT,
|
|
DB_USER,
|
|
)
|
|
|
|
# 글로벌 DB 풀 (앱 시작/종료 시 관리)
|
|
db_pool: Optional[aiomysql.Pool] = None
|
|
|
|
|
|
async def init_db_pool() -> aiomysql.Pool:
|
|
"""MariaDB 연결 풀 초기화"""
|
|
global db_pool
|
|
db_pool = await aiomysql.create_pool(
|
|
host=DB_HOST,
|
|
port=DB_PORT,
|
|
db=DB_NAME,
|
|
user=DB_USER,
|
|
password=DB_PASSWORD,
|
|
minsize=DB_POOL_MIN,
|
|
maxsize=DB_POOL_MAX,
|
|
# autocommit=False면 SELECT만 하고 반납된 커넥션에 열린 트랜잭션(옛 스냅샷)이
|
|
# 남아, 다른 커넥션이 커밋한 데이터(예: 방금 생성된 세션)를 못 읽는다.
|
|
# 다중 문장 트랜잭션은 connection.begin()을 명시적으로 사용한다.
|
|
autocommit=True,
|
|
charset="utf8mb4",
|
|
init_command="SET time_zone='+00:00'",
|
|
)
|
|
return db_pool
|
|
|
|
|
|
async def close_db_pool() -> None:
|
|
"""MariaDB 연결 풀 종료"""
|
|
global db_pool
|
|
if db_pool:
|
|
db_pool.close()
|
|
await db_pool.wait_closed()
|
|
db_pool = None
|
|
|
|
|
|
def get_db_pool() -> aiomysql.Pool:
|
|
"""현재 활성 DB 풀 반환. 없으면 RuntimeError"""
|
|
if not db_pool:
|
|
raise RuntimeError("DB pool not initialized. Call init_db_pool() first.")
|
|
return db_pool
|
|
|
|
|
|
async def run_with_connection(repository_call: Callable[..., Any], *args: Any) -> Any:
|
|
"""저장소 함수 하나를 **자기 커넥션**으로 실행한다 — `asyncio.gather` 로 묶기 위한 것.
|
|
|
|
DB 가 원격이라 질의 하나가 곧 왕복 약 12ms 다(2026-09-06 실측). 서로 기다릴 이유가 없는
|
|
읽기를 한 커넥션에서 순차로 내면 그 왕복이 그대로 더해진다. 커넥션을 갈라 같이 보내면
|
|
가장 느린 하나의 시간만 든다. 풀 최대치는 `DB_POOL_MAX`(기본 20).
|
|
|
|
⚠ **읽기에만 쓸 것.** 순서가 필요한 쓰기(한 트랜잭션 안의 UPDATE 들)를 이걸로 묶으면
|
|
커넥션이 갈려 트랜잭션이 깨진다.
|
|
"""
|
|
pool = get_db_pool()
|
|
async with pool.acquire() as connection:
|
|
return await repository_call(connection, *args)
|