fix: SQLite 멀티스레드 I/O 에러 해결
- 요청마다 새 SQLite 연결 생성 (new_connection=True) - 사용 후 명시적 close - 간헐적 'I/O operation on closed file' 에러 방지
This commit is contained in:
parent
870e40a6db
commit
76da7d9cd1
@ -3029,9 +3029,10 @@ def api_member_history(phone):
|
||||
|
||||
transaction_ids = [] # 적립된 거래번호 수집
|
||||
|
||||
# 1. 마일리지 내역 조회 (SQLite)
|
||||
# 1. 마일리지 내역 조회 (SQLite) - 새 연결 사용 (멀티스레드 안전)
|
||||
sqlite_conn = None
|
||||
try:
|
||||
sqlite_conn = db_manager.get_sqlite_connection()
|
||||
sqlite_conn = db_manager.get_sqlite_connection(new_connection=True)
|
||||
cursor = sqlite_conn.cursor()
|
||||
|
||||
# 사용자 정보 조회
|
||||
@ -3108,6 +3109,13 @@ def api_member_history(phone):
|
||||
|
||||
except Exception as e:
|
||||
logging.warning(f"마일리지 조회 실패: {e}")
|
||||
finally:
|
||||
# SQLite 연결 닫기
|
||||
if sqlite_conn:
|
||||
try:
|
||||
sqlite_conn.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
# 2. 전화번호로 POS 고객코드 조회 (MSSQL)
|
||||
cuscode = None
|
||||
|
||||
@ -185,18 +185,23 @@ class DatabaseManager:
|
||||
# 새 세션 생성
|
||||
return self.get_session(database)
|
||||
|
||||
def get_sqlite_connection(self):
|
||||
def get_sqlite_connection(self, new_connection=False):
|
||||
"""
|
||||
SQLite mileage.db 연결 반환 (싱글톤 패턴)
|
||||
최초 호출 시 스키마 자동 초기화
|
||||
SQLite mileage.db 연결 반환
|
||||
|
||||
Args:
|
||||
new_connection: True면 항상 새 연결 생성 (멀티스레드 안전)
|
||||
|
||||
Returns:
|
||||
sqlite3.Connection: SQLite 연결 객체
|
||||
"""
|
||||
# 연결 유효성 체크 강화
|
||||
# 새 연결 요청 시 항상 새로 생성
|
||||
if new_connection:
|
||||
return self._create_sqlite_connection()
|
||||
|
||||
# 기존 싱글톤 방식 (하위 호환)
|
||||
if self.sqlite_conn is not None:
|
||||
try:
|
||||
# 연결 상태 확인
|
||||
cursor = self.sqlite_conn.cursor()
|
||||
cursor.execute("SELECT 1")
|
||||
cursor.fetchone()
|
||||
@ -210,28 +215,30 @@ class DatabaseManager:
|
||||
self.sqlite_conn = None
|
||||
|
||||
if self.sqlite_conn is None:
|
||||
# 파일 존재 여부 확인
|
||||
is_new_db = not self.sqlite_db_path.exists()
|
||||
|
||||
# 연결 생성
|
||||
self.sqlite_conn = sqlite3.connect(
|
||||
str(self.sqlite_db_path),
|
||||
check_same_thread=False, # 멀티스레드 허용
|
||||
timeout=10.0 # 10초 대기
|
||||
)
|
||||
|
||||
# Row Factory 설정 (dict 형태로 결과 반환)
|
||||
self.sqlite_conn.row_factory = sqlite3.Row
|
||||
|
||||
# 신규 DB면 스키마 초기화
|
||||
if is_new_db:
|
||||
self.init_sqlite_schema()
|
||||
print(f"[DB Manager] SQLite 신규 DB 생성 완료: {self.sqlite_db_path}")
|
||||
else:
|
||||
print(f"[DB Manager] SQLite 기존 DB 연결: {self.sqlite_db_path}")
|
||||
self._migrate_sqlite()
|
||||
self.sqlite_conn = self._create_sqlite_connection()
|
||||
|
||||
return self.sqlite_conn
|
||||
|
||||
def _create_sqlite_connection(self):
|
||||
"""새 SQLite 연결 생성"""
|
||||
is_new_db = not self.sqlite_db_path.exists()
|
||||
|
||||
conn = sqlite3.connect(
|
||||
str(self.sqlite_db_path),
|
||||
check_same_thread=False,
|
||||
timeout=10.0
|
||||
)
|
||||
conn.row_factory = sqlite3.Row
|
||||
|
||||
if is_new_db:
|
||||
# 스키마 초기화 (임시로 self.sqlite_conn 설정)
|
||||
old_conn = self.sqlite_conn
|
||||
self.sqlite_conn = conn
|
||||
self.init_sqlite_schema()
|
||||
self.sqlite_conn = old_conn
|
||||
print(f"[DB Manager] SQLite 신규 DB 생성 완료: {self.sqlite_db_path}")
|
||||
|
||||
return conn
|
||||
|
||||
def init_sqlite_schema(self):
|
||||
"""
|
||||
|
||||
Loading…
Reference in New Issue
Block a user