feat: 迁移 Admin Repository 到 MySQL 8 (#79)
This commit is contained in:
@@ -8,13 +8,17 @@ import (
|
||||
"fmt"
|
||||
|
||||
"cmautobuy/admin/model"
|
||||
"github.com/go-sql-driver/mysql"
|
||||
)
|
||||
|
||||
// ErrIdempotencyConflict 表示同一个键提交了不同的内容。
|
||||
//
|
||||
// 这说明客户端弄错了——同一个键必须对应同一份内容。
|
||||
// 内容真的变了,应该用新的 attempt_id 生成新的键。
|
||||
var ErrIdempotencyConflict = errors.New("相同幂等键提交了不同内容")
|
||||
var (
|
||||
ErrIdempotencyConflict = errors.New("相同幂等键提交了不同内容")
|
||||
ErrIdempotencyAlreadySaved = errors.New("幂等键已被并发请求保存")
|
||||
)
|
||||
|
||||
// HashRequest 计算请求体的哈希,用来判断"同一个键"配的是不是"同一份内容"。
|
||||
func HashRequest(body []byte) string {
|
||||
@@ -31,7 +35,7 @@ func HashRequest(body []byte) string {
|
||||
func LookupIdempotent(q Execer, key, requestHash string) (string, bool, error) {
|
||||
var storedHash, storedBody string
|
||||
err := q.QueryRow(
|
||||
`SELECT request_hash, response_body FROM idempotency_keys WHERE key = ?`,
|
||||
"SELECT request_hash, response_body FROM idempotency_keys WHERE `key` = ?",
|
||||
key).Scan(&storedHash, &storedBody)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
@@ -52,10 +56,14 @@ func LookupIdempotent(q Execer, key, requestHash string) (string, bool, error) {
|
||||
// 分开写的话,业务写成功但幂等记录没写上,客户端重试就会被重复处理。
|
||||
func SaveIdempotent(q Execer, key, requestHash, responseBody string) error {
|
||||
_, err := q.Exec(
|
||||
`INSERT INTO idempotency_keys (key, request_hash, response_body, created_at)
|
||||
VALUES (?, ?, ?, ?)`,
|
||||
"INSERT INTO idempotency_keys (`key`, request_hash, response_body, created_at)\n"+
|
||||
" VALUES (?, ?, ?, ?)",
|
||||
key, requestHash, responseBody, model.NowISO())
|
||||
if err != nil {
|
||||
var mysqlErr *mysql.MySQLError
|
||||
if errors.As(err, &mysqlErr) && mysqlErr.Number == 1062 {
|
||||
return ErrIdempotencyAlreadySaved
|
||||
}
|
||||
return fmt.Errorf("保存幂等键失败: %w", err)
|
||||
}
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user