66 lines
2.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package mysql
import (
"context"
"database/sql"
"strings"
"time"
_ "github.com/go-sql-driver/mysql"
"hyapp/pkg/xerr"
)
// Repository 是 lucky-gift-service 的 MySQL 持久化入口。
// 幸运礼物的规则版本、RTP 窗口、单池水位、抽奖记录和返奖 outbox 必须落在同一个 owner 库,
// 调用方只能通过 service/grpc 进入,不能绕过事务边界直接修改这些表。
type Repository struct {
db *sql.DB
}
// Open 创建幸运礼物服务专用连接池并做启动探活。
// DSN 必须指向 hyapp_lucky_gift复用 activity 或 wallet 库会破坏 owner 边界,也会让 outbox 补偿读错事实。
func Open(ctx context.Context, dsn string) (*Repository, error) {
if strings.TrimSpace(dsn) == "" {
return nil, xerr.New(xerr.InvalidArgument, "mysql_dsn is required")
}
db, err := sql.Open("mysql", dsn)
if err != nil {
return nil, err
}
// 标准库默认连接数不设限;幸运礼物抽奖会持有多张表行锁,必须限制并发连接避免压垮 MySQL。
db.SetMaxOpenConns(20)
db.SetMaxIdleConns(10)
db.SetConnMaxLifetime(30 * time.Minute)
if err := db.PingContext(ctx); err != nil {
_ = db.Close()
return nil, err
}
return &Repository{db: db}, nil
}
// Migrate 只做本地/测试环境的轻量幂等兜底。
// 生产表结构仍以 deploy/mysql/initdb 和显式 migration 为准,避免服务启动时悄悄改动线上结构。
func (r *Repository) Migrate(ctx context.Context) error {
if r == nil || r.db == nil {
return xerr.New(xerr.Unavailable, "mysql repository is not configured")
}
// 当前拆分版本优先依赖完整初始化 SQL这里保留探活让 Docker 本地启动能在 DSN 错误时快速失败。
return r.db.PingContext(ctx)
}
// Close 释放连接池;服务关闭时先停止 worker 再关库,避免补偿协程拿到已关闭连接。
func (r *Repository) Close() error {
if r == nil || r.db == nil {
return nil
}
return r.db.Close()
}
// Ping 给健康检查使用,只确认 owner 库可访问,不代表钱包或 IM 下游可用。
func (r *Repository) Ping(ctx context.Context) error {
if r == nil || r.db == nil {
return xerr.New(xerr.Unavailable, "mysql repository is not configured")
}
return r.db.PingContext(ctx)
}