|
|
@@ -1,16 +1,19 @@
|
|
|
-// Code scaffolded by goctl. Safe to edit.
|
|
|
-// goctl 1.10.2
|
|
|
+// udeServer: CreateService 走事务 —— 同一事务内插 t_service + N 条 t_directory,
|
|
|
+// 任意一条 INSERT 失败,全部回滚,不留脏数据。
|
|
|
|
|
|
package logic
|
|
|
|
|
|
import (
|
|
|
"context"
|
|
|
+ "fmt"
|
|
|
+ "strings"
|
|
|
|
|
|
"udeServer/internal/model"
|
|
|
"udeServer/internal/svc"
|
|
|
"udeServer/internal/types"
|
|
|
|
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
|
+ "github.com/zeromicro/go-zero/core/stores/sqlx"
|
|
|
)
|
|
|
|
|
|
type CreateServiceLogic struct {
|
|
|
@@ -28,26 +31,54 @@ func NewCreateServiceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Cre
|
|
|
}
|
|
|
|
|
|
func (l *CreateServiceLogic) CreateService(req *types.CreateServiceReq) (*types.ServiceResp, error) {
|
|
|
- if err := checkId(req.Id); err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
+ var svcId int64
|
|
|
+ err := l.svcCtx.DB.Transact(func(session sqlx.Session) error {
|
|
|
+ // 把 model 绑到事务 session 上,后续所有写操作都走同一个连接/事务
|
|
|
+ svcModel := l.svcCtx.ServiceModel.WithSession(session)
|
|
|
+ dirModel := l.svcCtx.DirectoryModel.WithSession(session)
|
|
|
|
|
|
- data := &model.TService{
|
|
|
- Id: req.Id,
|
|
|
- Name: nullString(req.Name),
|
|
|
- Ip: nullString(req.Ip),
|
|
|
- Port: nullString(req.Port),
|
|
|
- Iden: nullString(req.Iden),
|
|
|
- KeyIden: nullString(req.KeyIden),
|
|
|
- KeyAlgo: nullString(req.KeyAlgo),
|
|
|
- Status: nullString(req.Status),
|
|
|
- }
|
|
|
- if _, err := l.svcCtx.ServiceModel.Insert(l.ctx, data); err != nil {
|
|
|
- l.Errorf("insert service %d failed: %v", req.Id, err)
|
|
|
+ // 1. 插服务
|
|
|
+ svcData := &model.TService{
|
|
|
+ Name: nullString(req.Name),
|
|
|
+ Ip: nullString(req.Ip),
|
|
|
+ Port: nullString(req.Port),
|
|
|
+ Iden: nullString(req.Iden),
|
|
|
+ KeyIden: nullString(req.KeyIden),
|
|
|
+ KeyAlgo: nullString(req.KeyAlgo),
|
|
|
+ Status: nullString(req.Status),
|
|
|
+ }
|
|
|
+ svcRes, err := svcModel.Insert(l.ctx, svcData)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("insert t_service: %w", err)
|
|
|
+ }
|
|
|
+ svcId, err = svcRes.LastInsertId()
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("get last insert id: %w", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 插保护目录(与上面的服务同事务,任一条失败整体回滚)
|
|
|
+ for _, dir := range req.Directories {
|
|
|
+ path := strings.TrimSpace(dir)
|
|
|
+ if path == "" {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ _, err := dirModel.Insert(l.ctx, &model.TDirectory{
|
|
|
+ ServiceId: nullInt64(svcId),
|
|
|
+ Directory: nullString(path),
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("insert t_directory[%s]: %w", path, err)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+ if err != nil {
|
|
|
+ l.Errorf("create service tx failed: %v", err)
|
|
|
return nil, err
|
|
|
}
|
|
|
|
|
|
- created, err := findService(l.ctx, l.svcCtx.ServiceModel, req.Id)
|
|
|
+ // 事务提交后再回查完整实体(CreateAt 由 DB 默认值生成)
|
|
|
+ created, err := findService(l.ctx, l.svcCtx.ServiceModel, svcId)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|