refactor: own subscription create transactions

This commit is contained in:
jxxghp
2026-08-21 20:37:31 +08:00
parent de2957b9de
commit 7de72e0e83
11 changed files with 840 additions and 120 deletions
+14 -2
View File
@@ -61,7 +61,13 @@ from app.adapters.external.server import (
)
from app.application.server.report import ServerReportService
from app.application.server.share import ServerSharingService
from app.db.session import close_database, get_async_db, get_db
from app.db.session import (
SessionFactory,
async_session_scope,
close_database,
get_async_db,
get_db,
)
from app.db.uow import SqlAlchemyAsyncUnitOfWork, SqlAlchemyUnitOfWork
from app.db.oper.subscribe import SubscribeOper
from app.db.oper.agentchat import AgentChatOper
@@ -90,6 +96,7 @@ from app.startup.managed_resources_initializer import (
init_managed_resources,
stop_managed_resources,
)
from app.startup.subscription import TransactionalSubscribeWriter
from app.adapters.web.security.access import set_superuser_token_payload_provider
from app.application.security.auth import build_superuser_token_payload
from app.application.image import configure_wallpaper_providers
@@ -465,7 +472,12 @@ async def init_modules():
workflow=lambda: WorkflowOper(),
plugin_data=lambda: PluginDataOper(),
)
configure_subscribe_writer(lambda: SubscribeOper())
configure_subscribe_writer(
lambda: TransactionalSubscribeWriter(
sync_session=SessionFactory,
async_session=async_session_scope,
)
)
# 托管资源只在这里装配声明与 adapter,具体资源仍由首个消费者显式激活。
init_managed_resources()
# 应用服务不反向依赖 Chain,由启动组合层注入壁纸来源。
+70
View File
@@ -0,0 +1,70 @@
"""订阅写入事务适配器的启动装配。"""
from collections.abc import Callable
from contextlib import AbstractAsyncContextManager
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import Session
from app.application.subscription.write import (
AfterCommitEffect,
AsyncAfterCommitEffect,
AsyncCreateSubscriptionCommand,
CreateSubscriptionCommand,
)
from app.db.oper.subscribe import SubscribeOper
from app.db.uow import SqlAlchemyAsyncUnitOfWork, SqlAlchemyUnitOfWork
class TransactionalSubscribeWriter:
"""为每次订阅新增创建独占会话,并把提交权交给 Application Command。"""
def __init__(
self,
sync_session: Callable[[], Session],
async_session: Callable[
[],
AbstractAsyncContextManager[AsyncSession],
],
) -> None:
"""注入同步会话工厂和异步会话作用域。"""
self._sync_session = sync_session
self._async_session = async_session
def add(
self,
identity: dict,
payload: dict,
username: str | None = None,
after_commit: AfterCommitEffect | None = None,
) -> tuple[int, str]:
"""在独占同步会话内执行一次完整订阅新增事务。"""
session = self._sync_session()
try:
command = CreateSubscriptionCommand(
repository=SubscribeOper(session),
unit_of_work=SqlAlchemyUnitOfWork(session),
)
return command.execute(identity, payload, username, after_commit)
finally:
session.close()
async def async_add(
self,
identity: dict,
payload: dict,
username: str | None = None,
after_commit: AsyncAfterCommitEffect | None = None,
) -> tuple[int, str]:
"""在独占异步会话作用域内执行一次完整订阅新增事务。"""
async with self._async_session() as session:
command = AsyncCreateSubscriptionCommand(
repository=SubscribeOper(session),
unit_of_work=SqlAlchemyAsyncUnitOfWork(session),
)
return await command.execute(
identity,
payload,
username,
after_commit,
)