update
This commit is contained in:
parent
861d5258fb
commit
e81a69e2e6
@ -56,6 +56,7 @@ class CouponInfo(BaseModel):
|
|||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
amount: float
|
amount: float
|
||||||
|
expire_time: datetime
|
||||||
coupon_type: CouponType
|
coupon_type: CouponType
|
||||||
create_time: datetime
|
create_time: datetime
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from sqlalchemy import create_engine, event
|
from sqlalchemy import create_engine, event, text
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
from sqlalchemy.orm import sessionmaker, scoped_session
|
from sqlalchemy.orm import sessionmaker, scoped_session
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
@ -22,7 +22,15 @@ engine = create_engine(
|
|||||||
pool_size=10, # 连接池大小
|
pool_size=10, # 连接池大小
|
||||||
max_overflow=20, # 允许的最大连接数超出pool_size的数量
|
max_overflow=20, # 允许的最大连接数超出pool_size的数量
|
||||||
pool_timeout=30, # 获取连接的超时时间(秒)
|
pool_timeout=30, # 获取连接的超时时间(秒)
|
||||||
echo_pool=settings.DEBUG # 在调试模式下记录连接池事件
|
echo_pool=settings.DEBUG, # 在调试模式下记录连接池事件
|
||||||
|
# 添加以下参数以增强连接稳定性
|
||||||
|
pool_reset_on_return='commit', # 在连接返回池时重置连接状态
|
||||||
|
isolation_level='READ COMMITTED', # 设置事务隔离级别
|
||||||
|
connect_args={
|
||||||
|
'connect_timeout': 10, # 连接超时时间(秒)
|
||||||
|
'read_timeout': 30, # 读取超时时间(秒)
|
||||||
|
'write_timeout': 30 # 写入超时时间(秒)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
# 创建线程安全的会话工厂
|
# 创建线程安全的会话工厂
|
||||||
@ -59,10 +67,14 @@ def checkout(dbapi_connection, connection_record, connection_proxy):
|
|||||||
# 执行简单查询测试连接
|
# 执行简单查询测试连接
|
||||||
cursor = dbapi_connection.cursor()
|
cursor = dbapi_connection.cursor()
|
||||||
cursor.execute("SELECT 1")
|
cursor.execute("SELECT 1")
|
||||||
|
cursor.fetchone() # 确保实际获取结果
|
||||||
cursor.close()
|
cursor.close()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# 如果连接无效,断开它
|
# 如果连接无效,断开它并尝试重新连接
|
||||||
logger.warning(f"检测到无效的数据库连接: {str(e)}")
|
logger.warning(f"检测到无效的数据库连接: {str(e)}")
|
||||||
|
# 标记连接为无效
|
||||||
|
connection_record.invalidate()
|
||||||
|
# 强制处理连接池
|
||||||
connection_proxy._pool.dispose()
|
connection_proxy._pool.dispose()
|
||||||
raise
|
raise
|
||||||
|
|
||||||
@ -113,7 +125,25 @@ def after_cursor_execute(conn, cursor, statement, parameters, context, executema
|
|||||||
def get_db():
|
def get_db():
|
||||||
"""获取数据库会话"""
|
"""获取数据库会话"""
|
||||||
session_id = threading.get_ident()
|
session_id = threading.get_ident()
|
||||||
session = SessionLocal()
|
db = None
|
||||||
|
retry_count = 0
|
||||||
|
max_retries = 3
|
||||||
|
|
||||||
|
while retry_count < max_retries:
|
||||||
|
try:
|
||||||
|
db = SessionLocal()
|
||||||
|
# 测试连接是否有效
|
||||||
|
db.execute(text("SELECT 1"))
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
retry_count += 1
|
||||||
|
if db:
|
||||||
|
db.close()
|
||||||
|
if retry_count >= max_retries:
|
||||||
|
logger.error(f"无法建立数据库连接,已重试 {retry_count} 次: {str(e)}")
|
||||||
|
raise
|
||||||
|
logger.warning(f"数据库连接失败,正在重试 ({retry_count}/{max_retries}): {str(e)}")
|
||||||
|
time.sleep(0.5) # 短暂延迟后重试
|
||||||
|
|
||||||
# 记录活跃会话
|
# 记录活跃会话
|
||||||
with session_lock:
|
with session_lock:
|
||||||
@ -123,10 +153,11 @@ def get_db():
|
|||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
yield session
|
yield db
|
||||||
finally:
|
finally:
|
||||||
# 关闭会话并从活跃会话中移除
|
# 关闭会话并从活跃会话中移除
|
||||||
session.close()
|
if db:
|
||||||
|
db.close()
|
||||||
with session_lock:
|
with session_lock:
|
||||||
if session_id in active_sessions:
|
if session_id in active_sessions:
|
||||||
del active_sessions[session_id]
|
del active_sessions[session_id]
|
||||||
@ -134,9 +165,27 @@ def get_db():
|
|||||||
@contextmanager
|
@contextmanager
|
||||||
def get_db_context():
|
def get_db_context():
|
||||||
"""上下文管理器版本的get_db,用于非依赖项场景"""
|
"""上下文管理器版本的get_db,用于非依赖项场景"""
|
||||||
session = SessionLocal()
|
session = None
|
||||||
|
retry_count = 0
|
||||||
|
max_retries = 3
|
||||||
session_id = threading.get_ident()
|
session_id = threading.get_ident()
|
||||||
|
|
||||||
|
while retry_count < max_retries:
|
||||||
|
try:
|
||||||
|
session = SessionLocal()
|
||||||
|
# 测试连接是否有效
|
||||||
|
session.execute(text("SELECT 1"))
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
retry_count += 1
|
||||||
|
if session:
|
||||||
|
session.close()
|
||||||
|
if retry_count >= max_retries:
|
||||||
|
logger.error(f"无法建立数据库连接,已重试 {retry_count} 次: {str(e)}")
|
||||||
|
raise
|
||||||
|
logger.warning(f"数据库连接失败,正在重试 ({retry_count}/{max_retries}): {str(e)}")
|
||||||
|
time.sleep(0.5) # 短暂延迟后重试
|
||||||
|
|
||||||
# 记录活跃会话
|
# 记录活跃会话
|
||||||
with session_lock:
|
with session_lock:
|
||||||
active_sessions[session_id] = {
|
active_sessions[session_id] = {
|
||||||
@ -148,9 +197,11 @@ def get_db_context():
|
|||||||
yield session
|
yield session
|
||||||
session.commit()
|
session.commit()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
if session:
|
||||||
session.rollback()
|
session.rollback()
|
||||||
raise e
|
raise e
|
||||||
finally:
|
finally:
|
||||||
|
if session:
|
||||||
session.close()
|
session.close()
|
||||||
with session_lock:
|
with session_lock:
|
||||||
if session_id in active_sessions:
|
if session_id in active_sessions:
|
||||||
|
|||||||
BIN
jobs.sqlite
BIN
jobs.sqlite
Binary file not shown.
Loading…
Reference in New Issue
Block a user