2026-07-03 22:04:39 +08:00

67 lines
1.9 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 实现 user-service 的 MySQL 持久化边界。
package mysql
import (
"context"
"database/sql"
"strings"
"time"
"hyapp/pkg/xerr"
)
// Repository 是 user-service 的 MySQL 持久化入口。
// 方法按领域拆到 user_repository、identity_repository 和 auth_repository避免一个文件混合多条业务线。
type Repository struct {
// db 是标准库连接池,事务和普通查询都从这里创建。
db *sql.DB
}
// Open 创建 MySQL 连接池并做启动 ping。
func Open(ctx context.Context, dsn string) (*Repository, error) {
if strings.TrimSpace(dsn) == "" {
// 本地和线上运行都必须显式提供 DSN空 DSN 代表应用装配错误。
return nil, xerr.New(xerr.InvalidArgument, "mysql_dsn is required")
}
// sql.Open 只创建连接池,真实连通性由 PingContext 验证。
db, err := sql.Open("mysql", dsn)
if err != nil {
return nil, err
}
// 标准库默认不限制连接数,高并发下会打爆 MySQL max_connections必须显式设上限。
db.SetMaxOpenConns(20)
db.SetMaxIdleConns(10)
// 长连接定期轮换,避免云数据库或网络层回收导致长期坏连接驻留。
db.SetConnMaxLifetime(30 * time.Minute)
if err := db.PingContext(ctx); err != nil {
// 启动探测失败时关闭连接池,避免返回半初始化 repository。
_ = db.Close()
return nil, err
}
return &Repository{db: db}, nil
}
// Close 释放 MySQL 连接池。
func (r *Repository) Close() error {
if r == nil || r.db == nil {
// Close 允许重复调用和 nil 调用,方便 App.Close 幂等释放。
return nil
}
return r.db.Close()
}
// Ping 验证 MySQL 当前可用。
func (r *Repository) Ping(ctx context.Context) error {
if r == nil || r.db == nil {
// 没有连接池时明确返回 unavailable。
return xerr.New(xerr.Unavailable, "mysql repository is not configured")
}
return r.db.PingContext(ctx)
}