♻️ refactor(outbox): 抽离通用事件总线,并完成 event_type-only 收口 - ✨ 新增 `infra` 层通用 `EventBus` / `EventContract`,统一事件发布与消费协议 - 🔄 将聊天持久化链路调整为通过 `service/events` 注册 handler 并发布事件,进一步解耦业务逻辑与异步处理流程 - 🧹 移除 `chat_history_async` 旧适配实现,以及基于 `biz_type` 的兼容分发逻辑 - 📝 更新 Outbox 异步持久化决策记录,明确保留方案 A,并正式启用方案 B - 📚 同步更新 README 中关于 Outbox + Kafka 可靠异步链路的说明 - 🚚 当前 `outbox + kafka` 已与项目业务链路完全解耦,沉淀为通用、可靠性更强的消息队列能力;后续将参考消息队列的典型使用方式,逐步扩展到更多业务场景 - ✨ 补充跨不同分类事务管理器中的 `agent dao` 注册与接入支持
62 lines
1.7 KiB
Go
62 lines
1.7 KiB
Go
package dao
|
||
|
||
import (
|
||
"context"
|
||
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// RepoManager 聚合所有 DAO,供服务层做跨仓储事务编排。
|
||
type RepoManager struct {
|
||
db *gorm.DB
|
||
Schedule *ScheduleDAO
|
||
Task *TaskDAO
|
||
Course *CourseDAO
|
||
TaskClass *TaskClassDAO
|
||
User *UserDAO
|
||
Agent *AgentDAO
|
||
}
|
||
|
||
func NewManager(db *gorm.DB) *RepoManager {
|
||
return &RepoManager{
|
||
db: db,
|
||
Schedule: NewScheduleDAO(db),
|
||
Task: NewTaskDAO(db),
|
||
Course: NewCourseDAO(db),
|
||
TaskClass: NewTaskClassDAO(db),
|
||
User: NewUserDAO(db),
|
||
Agent: NewAgentDAO(db),
|
||
}
|
||
}
|
||
|
||
// WithTx 基于外部事务句柄构造“同事务 RepoManager”。
|
||
//
|
||
// 职责边界:
|
||
// 1. 只做 DAO 依赖重绑定,不开启/提交/回滚事务;
|
||
// 2. 让服务层在一个 tx 内调用多个 DAO 方法;
|
||
// 3. 适用于 outbox 消费处理器这类“基础设施事务 + 业务事务合并”的场景。
|
||
func (m *RepoManager) WithTx(tx *gorm.DB) *RepoManager {
|
||
return &RepoManager{
|
||
db: tx,
|
||
Schedule: m.Schedule.WithTx(tx),
|
||
Task: m.Task.WithTx(tx),
|
||
TaskClass: m.TaskClass.WithTx(tx),
|
||
Course: m.Course.WithTx(tx),
|
||
User: m.User.WithTx(tx),
|
||
Agent: m.Agent.WithTx(tx),
|
||
}
|
||
}
|
||
|
||
// Transaction 开启事务并把“同事务 RepoManager”传给回调。
|
||
//
|
||
// 使用约束:
|
||
// 1. 回调里应只使用 txM 下挂 DAO,避免混入事务外句柄;
|
||
// 2. 回调返回 error 会触发整体回滚;
|
||
// 3. 回调返回 nil 表示提交事务。
|
||
func (m *RepoManager) Transaction(ctx context.Context, fn func(txM *RepoManager) error) error {
|
||
return m.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||
txM := m.WithTx(tx)
|
||
return fn(txM)
|
||
})
|
||
}
|