fix(server): refactor server model methods to support transaction handling

This commit is contained in:
Chang lue Tsen
2025-05-06 13:21:27 +09:00
parent 38bcacc9e7
commit 3cadd9e621
3 changed files with 32 additions and 33 deletions
+17 -10
View File
@@ -23,10 +23,10 @@ type (
customServerLogicModel
}
serverModel interface {
Insert(ctx context.Context, data *Server) error
Insert(ctx context.Context, data *Server, tx ...*gorm.DB) error
FindOne(ctx context.Context, id int64) (*Server, error)
Update(ctx context.Context, data *Server) error
Delete(ctx context.Context, id int64) error
Update(ctx context.Context, data *Server, tx ...*gorm.DB) error
Delete(ctx context.Context, id int64, tx ...*gorm.DB) error
Transaction(ctx context.Context, fn func(db *gorm.DB) error) error
}
@@ -77,8 +77,11 @@ func (m *defaultServerModel) getCacheKeys(data *Server) []string {
return cacheKeys
}
func (m *defaultServerModel) Insert(ctx context.Context, data *Server) error {
func (m *defaultServerModel) Insert(ctx context.Context, data *Server, tx ...*gorm.DB) error {
err := m.ExecCtx(ctx, func(conn *gorm.DB) error {
if len(tx) > 0 {
conn = tx[0]
}
return conn.Create(&data).Error
}, m.getCacheKeys(data)...)
return err
@@ -98,19 +101,21 @@ func (m *defaultServerModel) FindOne(ctx context.Context, id int64) (*Server, er
}
}
func (m *defaultServerModel) Update(ctx context.Context, data *Server) error {
func (m *defaultServerModel) Update(ctx context.Context, data *Server, tx ...*gorm.DB) error {
old, err := m.FindOne(ctx, data.Id)
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
err = m.ExecCtx(ctx, func(conn *gorm.DB) error {
db := conn
return db.Save(data).Error
if len(tx) > 0 {
conn = tx[0]
}
return conn.Save(data).Error
}, m.getCacheKeys(old)...)
return err
}
func (m *defaultServerModel) Delete(ctx context.Context, id int64) error {
func (m *defaultServerModel) Delete(ctx context.Context, id int64, tx ...*gorm.DB) error {
data, err := m.FindOne(ctx, id)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
@@ -119,8 +124,10 @@ func (m *defaultServerModel) Delete(ctx context.Context, id int64) error {
return err
}
err = m.ExecCtx(ctx, func(conn *gorm.DB) error {
db := conn
return db.Delete(&Server{}, id).Error
if len(tx) > 0 {
conn = tx[0]
}
return conn.Delete(&Server{}, id).Error
}, m.getCacheKeys(data)...)
return err
}
+9 -20
View File
@@ -52,33 +52,26 @@ func (*Server) TableName() string {
func (s *Server) BeforeDelete(tx *gorm.DB) error {
logger.Debugf("[Server] BeforeDelete")
if err := tx.Exec("UPDATE `server` SET sort = sort - 1 WHERE sort > ?", s.Sort).Error; err != nil {
return err
}
// 删除后重新排序,防止因 sort 缺口导致问题
if err := reorderSort(tx); err != nil {
return err
}
return nil
}
func (s *Server) BeforeUpdate(tx *gorm.DB) error {
logger.Debugf("[Server] BeforeUpdate")
var count int64
if err := tx.Model(&Server{}).Where("sort = ? AND id != ?", s.Sort, s.Id).Count(&count).Error; err != nil {
if err := tx.Set("gorm:query_option", "FOR UPDATE").Model(&Server{}).
Where("sort = ? AND id != ?", s.Sort, s.Id).Count(&count).Error; err != nil {
return err
}
if count > 0 {
logger.Debugf("[Server] Duplicate sort found, reordering...")
if err := reorderSort(tx); err != nil {
var maxSort int64
if err := tx.Model(&Server{}).Select("MAX(sort)").Scan(&maxSort).Error; err != nil {
return err
}
s.Sort = maxSort + 1
}
return nil
}
@@ -191,17 +184,13 @@ func (RuleGroup) TableName() string {
}
func reorderSort(tx *gorm.DB) error {
var servers []*Server
if err := tx.Model(&Server{}).Order("sort ASC").Find(&servers).Error; err != nil {
var servers []Server
if err := tx.Order("sort, id").Find(&servers).Error; err != nil {
return err
}
for i, server := range servers {
newSort := int64(i + 1)
if server.Sort != newSort {
if err := tx.Model(&Server{}).
Where("id = ?", server.Id).
Update("sort", newSort).Error; err != nil {
if server.Sort != int64(i)+1 {
if err := tx.Exec("UPDATE `server` SET sort = ? WHERE id = ?", i+1, server.Id).Error; err != nil {
return err
}
}