Browse Source

完成事务

yjp 1 year ago
parent
commit
1f98c13c74

+ 21 - 8
binding/entity_crud/callbacks.go

@@ -7,8 +7,9 @@ import (
 
 type Callbacks[O any] struct {
 	BeforeDBOperate func(e domain.Entity, dbExecutor database.Executor) error
-	OnReturn        func(e domain.Entity, dbExecutor database.Executor, output O) (O, error)
-	OnError         func(e domain.Entity, err error, dbExecutor database.Executor, defaultErrOutput O) (O, error)
+	AfterDBOperate  func(e domain.Entity, dbExecutor database.Executor) error
+	OnSuccessReturn func(e domain.Entity, dbExecutor database.Executor, output O) (O, error)
+	OnErrorReturn   func(e domain.Entity, err error, dbExecutor database.Executor, defaultErrOutput O) (O, error)
 }
 
 func callbackBeforeDBOperate[O any](callbacks *Callbacks[O], e domain.Entity, dbExecutor database.Executor) error {
@@ -23,25 +24,37 @@ func callbackBeforeDBOperate[O any](callbacks *Callbacks[O], e domain.Entity, db
 	return nil
 }
 
-func callbackOnReturn[O any](callbacks *Callbacks[O], e domain.Entity, dbExecutor database.Executor, output O) (O, error) {
+func callbackAfterDBOperate[O any](callbacks *Callbacks[O], e domain.Entity, dbExecutor database.Executor) error {
+	if callbacks == nil {
+		return nil
+	}
+
+	if callbacks.AfterDBOperate == nil {
+		return callbacks.AfterDBOperate(e, dbExecutor)
+	}
+
+	return nil
+}
+
+func callbackOnSuccessReturn[O any](callbacks *Callbacks[O], e domain.Entity, dbExecutor database.Executor, output O) (O, error) {
 	if callbacks == nil {
 		return output, nil
 	}
 
-	if callbacks.OnReturn == nil {
-		return callbacks.OnReturn(e, dbExecutor, output)
+	if callbacks.OnSuccessReturn == nil {
+		return callbacks.OnSuccessReturn(e, dbExecutor, output)
 	}
 
 	return output, nil
 }
 
-func callbackOnError[O any](callbacks *Callbacks[O], e domain.Entity, err error, dbExecutor database.Executor, defaultErrOutput O) (O, error) {
+func callbackOnErrorReturn[O any](callbacks *Callbacks[O], e domain.Entity, err error, dbExecutor database.Executor, defaultErrOutput O) (O, error) {
 	if callbacks == nil {
 		return defaultErrOutput, err
 	}
 
-	if callbacks.OnError == nil {
-		return callbacks.OnError(e, err, dbExecutor, defaultErrOutput)
+	if callbacks.OnErrorReturn == nil {
+		return callbacks.OnErrorReturn(e, err, dbExecutor, defaultErrOutput)
 	}
 
 	return defaultErrOutput, err

+ 50 - 25
binding/entity_crud/service.go

@@ -24,12 +24,12 @@ func CommonEntityCreate(tableName string, dbExecutor database.Executor, callback
 
 		err := e.GenerateID()
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, "")
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, "")
 		}
 
 		err = callbackBeforeDBOperate(callbacks, e, dbExecutor)
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, "")
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, "")
 		}
 
 		err = database.InsertEntity(dbExecutor, tableName, e)
@@ -38,10 +38,15 @@ func CommonEntityCreate(tableName string, dbExecutor database.Executor, callback
 				err = fserr.New(e.DomainCNName() + "已存在")
 			}
 
-			return callbackOnError(callbacks, e, err, dbExecutor, "")
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, "")
 		}
 
-		return callbackOnReturn(callbacks, e, dbExecutor, e.GetID())
+		err = callbackAfterDBOperate(callbacks, e, dbExecutor)
+		if err != nil {
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, "")
+		}
+
+		return callbackOnSuccessReturn(callbacks, e, dbExecutor, e.GetID())
 	}
 }
 
@@ -54,7 +59,7 @@ func CommonEntityDelete(tableName string, dbExecutor database.Executor, callback
 
 		if strutils.IsStringEmpty(e.GetID()) {
 			err := fserr.New("领域实体ID为空")
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
 		exist, err := database.CheckExist(dbExecutor, &sql.CheckExistExecuteParams{
@@ -62,25 +67,30 @@ func CommonEntityDelete(tableName string, dbExecutor database.Executor, callback
 			Conditions: sql.NewConditions().Equal(e.IDColumnName(), e.GetID()),
 		})
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
 		if !exist {
 			err := fserr.New(e.DomainCNName() + "不存在")
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
 		err = callbackBeforeDBOperate(callbacks, e, dbExecutor)
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
 		err = database.DeleteEntity(dbExecutor, tableName, e)
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
+		}
+
+		err = callbackAfterDBOperate(callbacks, e, dbExecutor)
+		if err != nil {
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
-		return callbackOnReturn(callbacks, e, dbExecutor, nil)
+		return callbackOnSuccessReturn(callbacks, e, dbExecutor, nil)
 	}
 }
 
@@ -93,7 +103,7 @@ func CommonEntityUpdate(tableName string, dbExecutor database.Executor, callback
 
 		if strutils.IsStringEmpty(e.GetID()) {
 			err := fserr.New("领域实体ID为空")
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
 		exist, err := database.CheckExist(dbExecutor, &sql.CheckExistExecuteParams{
@@ -101,25 +111,30 @@ func CommonEntityUpdate(tableName string, dbExecutor database.Executor, callback
 			Conditions: sql.NewConditions().Equal(e.IDColumnName(), e.GetID()),
 		})
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
 		if !exist {
 			err := fserr.New(e.DomainCNName() + "不存在")
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
 		err = callbackBeforeDBOperate(callbacks, e, dbExecutor)
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
 		err = database.UpdateEntity(dbExecutor, tableName, e)
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
-		return callbackOnReturn(callbacks, e, dbExecutor, nil)
+		err = callbackAfterDBOperate(callbacks, e, dbExecutor)
+		if err != nil {
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
+		}
+
+		return callbackOnSuccessReturn(callbacks, e, dbExecutor, nil)
 	}
 }
 
@@ -158,7 +173,7 @@ func CommonEntityQuery[O any](tableName string, dbExecutor database.Executor, ca
 
 		err = callbackBeforeDBOperate(callbacks, e, dbExecutor)
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, response.InfosData[O]{})
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, response.InfosData[O]{})
 		}
 
 		results, totalCount, err := database.Query(dbExecutor, &sql.QueryExecuteParams{
@@ -168,13 +183,18 @@ func CommonEntityQuery[O any](tableName string, dbExecutor database.Executor, ca
 			PageSize:   queryDTO.GetPageSize(),
 		})
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, response.InfosData[O]{})
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, response.InfosData[O]{})
+		}
+
+		err = callbackAfterDBOperate(callbacks, e, dbExecutor)
+		if err != nil {
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, response.InfosData[O]{})
 		}
 
 		infos := make([]O, 0)
 		err = sql.ParseSqlResult(results, &infos)
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, response.InfosData[O]{})
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, response.InfosData[O]{})
 		}
 
 		output := response.InfosData[O]{
@@ -183,7 +203,7 @@ func CommonEntityQuery[O any](tableName string, dbExecutor database.Executor, ca
 			PageNo:     queryDTO.GetPageNo(),
 		}
 
-		return callbackOnReturn(callbacks, e, dbExecutor, output)
+		return callbackOnSuccessReturn(callbacks, e, dbExecutor, output)
 	}
 }
 
@@ -202,12 +222,12 @@ func CommonEntityQueryByID[O any](tableName string, dbExecutor database.Executor
 
 		if strutils.IsStringEmpty(e.GetID()) {
 			err := fserr.New("领域实体ID为空")
-			return callbackOnError(callbacks, e, err, dbExecutor, outputZero)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, outputZero)
 		}
 
 		err := callbackBeforeDBOperate(callbacks, e, dbExecutor)
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, outputZero)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, outputZero)
 		}
 
 		result, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{
@@ -215,7 +235,12 @@ func CommonEntityQueryByID[O any](tableName string, dbExecutor database.Executor
 			Conditions: sql.NewConditions().Equal(e.IDColumnName(), e.GetID()),
 		})
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, outputZero)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, outputZero)
+		}
+
+		err = callbackAfterDBOperate(callbacks, e, dbExecutor)
+		if err != nil {
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, outputZero)
 		}
 
 		var info O
@@ -228,9 +253,9 @@ func CommonEntityQueryByID[O any](tableName string, dbExecutor database.Executor
 
 		err = sql.ParseSqlResult(result, infoPointer)
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, outputZero)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, outputZero)
 		}
 
-		return callbackOnReturn(callbacks, e, dbExecutor, info)
+		return callbackOnSuccessReturn(callbacks, e, dbExecutor, info)
 	}
 }

+ 60 - 21
binding/entity_crud/simple.go

@@ -30,12 +30,21 @@ type Simple[O any] struct {
 	// 创建使用的DTO
 	CreateDTO request.DTO
 
+	// 创建是否使用事务
+	CreateNeedTx bool
+
 	// 删除使用的DTO,注意是WithID类型
 	DeleteDTO request.WithID
 
+	// 删除是否使用事务
+	DeleteNeedTx bool
+
 	// 更新使用的DTO,注意是WithID类型
 	UpdateDTO request.WithID
 
+	// 根性是否使用事务
+	UpdateNeedTx bool
+
 	// 查询使用的DTO,注意是Query类型
 	QueryDTO request.Query
 
@@ -47,31 +56,61 @@ func (crud *Simple[O]) bind(binder *binding.Binder) {
 	dbExecutor := binder.ChooseDBExecutor(crud.DBExecutorType)
 
 	// 创建班级
-	binding.PostBind(binder, &binding.SimpleBindItem[string]{
-		Path:         crud.DomainPath + "/create",
-		ResponseFunc: response.SendIDResponse[string],
-		DTO:          crud.CreateDTO,
-		Objects:      []domain.Object{crud.Entity},
-		ServiceFunc:  CommonEntityCreate(crud.TableName, dbExecutor, nil),
-	})
+	if !crud.CreateNeedTx {
+		binding.PostBind(binder, &binding.SimpleBindItem[string]{
+			Path:         crud.DomainPath + "/create",
+			ResponseFunc: response.SendIDResponse[string],
+			DTO:          crud.CreateDTO,
+			Objects:      []domain.Object{crud.Entity},
+			ServiceFunc:  CommonEntityCreate(crud.TableName, dbExecutor, nil),
+		})
+	} else {
+		binding.PostBind(binder, &binding.SimpleBindItem[string]{
+			Path:         crud.DomainPath + "/create",
+			ResponseFunc: response.SendIDResponse[string],
+			DTO:          crud.CreateDTO,
+			Objects:      []domain.Object{crud.Entity},
+			ServiceFunc:  CommonEntityCreateTx(crud.TableName, dbExecutor, nil),
+		})
+	}
 
 	// 删除班级
-	binding.DeleteBind(binder, &binding.SimpleBindItem[any]{
-		Path:         crud.DomainPath + "/:id/delete",
-		ResponseFunc: response.SendMsgResponse,
-		DTO:          crud.DeleteDTO,
-		Objects:      []domain.Object{crud.Entity},
-		ServiceFunc:  CommonEntityDelete(crud.TableName, dbExecutor, nil),
-	})
+	if !crud.DeleteNeedTx {
+		binding.DeleteBind(binder, &binding.SimpleBindItem[any]{
+			Path:         crud.DomainPath + "/:id/delete",
+			ResponseFunc: response.SendMsgResponse,
+			DTO:          crud.DeleteDTO,
+			Objects:      []domain.Object{crud.Entity},
+			ServiceFunc:  CommonEntityDelete(crud.TableName, dbExecutor, nil),
+		})
+	} else {
+		binding.DeleteBind(binder, &binding.SimpleBindItem[any]{
+			Path:         crud.DomainPath + "/:id/delete",
+			ResponseFunc: response.SendMsgResponse,
+			DTO:          crud.DeleteDTO,
+			Objects:      []domain.Object{crud.Entity},
+			ServiceFunc:  CommonEntityDeleteTx(crud.TableName, dbExecutor, nil),
+		})
+	}
 
 	// 修改班级
-	binding.PutBind(binder, &binding.SimpleBindItem[any]{
-		Path:         crud.DomainPath + "/update",
-		ResponseFunc: response.SendMsgResponse,
-		DTO:          crud.UpdateDTO,
-		Objects:      []domain.Object{crud.Entity},
-		ServiceFunc:  CommonEntityUpdate(crud.TableName, dbExecutor, nil),
-	})
+	if !crud.UpdateNeedTx {
+		binding.PutBind(binder, &binding.SimpleBindItem[any]{
+			Path:         crud.DomainPath + "/update",
+			ResponseFunc: response.SendMsgResponse,
+			DTO:          crud.UpdateDTO,
+			Objects:      []domain.Object{crud.Entity},
+			ServiceFunc:  CommonEntityUpdate(crud.TableName, dbExecutor, nil),
+		})
+	} else {
+		binding.PutBind(binder, &binding.SimpleBindItem[any]{
+			Path:         crud.DomainPath + "/update",
+			ResponseFunc: response.SendMsgResponse,
+			DTO:          crud.UpdateDTO,
+			Objects:      []domain.Object{crud.Entity},
+			ServiceFunc:  CommonEntityUpdateTx(crud.TableName, dbExecutor, nil),
+		})
+	}
 
 	// 查询班级
 	binding.GetBind(binder, &binding.SimpleBindItem[response.InfosData[O]]{

+ 0 - 93
binding/entity_crud/transaction.go

@@ -1,93 +0,0 @@
-package entity_crud
-
-import (
-	"git.sxidc.com/go-framework/baize/binding"
-	"git.sxidc.com/go-framework/baize/binding/request"
-	"git.sxidc.com/go-framework/baize/binding/response"
-	"git.sxidc.com/go-framework/baize/domain"
-)
-
-func BindTransaction[O any](binder *binding.Binder, crud *Simple[O]) {
-	crud.bind(binder)
-}
-
-// Transaction 实体CRUD(可选择使用事务)的Bind参数
-type Transaction[O any] struct {
-	// 使用的领域实体,注意是Entity类型
-	Entity domain.Entity
-
-	// 表名
-	TableName string
-
-	// 选择要使用的数据库Executor
-	// DBExecutorOperations operations 数据库操作
-	// DBExecutorDataService data_service 数据服务
-	DBExecutorType string
-
-	// URL领域相对路径,如/class,后面会自动补充
-	DomainPath string
-
-	// 创建使用的DTO
-	CreateDTO request.DTO
-
-	// 删除使用的DTO,注意是WithID类型
-	DeleteDTO request.WithID
-
-	// 更新使用的DTO,注意是WithID类型
-	UpdateDTO request.WithID
-
-	// 查询使用的DTO,注意是Query类型
-	QueryDTO request.Query
-
-	// 根据ID查询使用的DTO,注意是WithID类型
-	QueryByIDDTO request.WithID
-}
-
-func (crud *Simple[O]) bind(binder *binding.Binder) {
-	dbExecutor := binder.ChooseDBExecutor(crud.DBExecutorType)
-
-	// 创建班级
-	binding.PostBind(binder, &binding.SimpleBindItem[string]{
-		Path:         crud.DomainPath + "/create",
-		ResponseFunc: response.SendIDResponse[string],
-		DTO:          crud.CreateDTO,
-		Objects:      []domain.Object{crud.Entity},
-		ServiceFunc:  CommonEntityCreate(crud.TableName, dbExecutor, nil),
-	})
-
-	// 删除班级
-	binding.DeleteBind(binder, &binding.SimpleBindItem[any]{
-		Path:         crud.DomainPath + "/:id/delete",
-		ResponseFunc: response.SendMsgResponse,
-		DTO:          crud.DeleteDTO,
-		Objects:      []domain.Object{crud.Entity},
-		ServiceFunc:  CommonEntityDelete(crud.TableName, dbExecutor, nil),
-	})
-
-	// 修改班级
-	binding.PutBind(binder, &binding.SimpleBindItem[any]{
-		Path:         crud.DomainPath + "/update",
-		ResponseFunc: response.SendMsgResponse,
-		DTO:          crud.UpdateDTO,
-		Objects:      []domain.Object{crud.Entity},
-		ServiceFunc:  CommonEntityUpdate(crud.TableName, dbExecutor, nil),
-	})
-
-	// 查询班级
-	binding.GetBind(binder, &binding.SimpleBindItem[response.InfosData[O]]{
-		Path:         crud.DomainPath + "/query",
-		ResponseFunc: response.SendInfosResponse[O],
-		DTO:          crud.QueryDTO,
-		Objects:      []domain.Object{crud.Entity},
-		ServiceFunc:  CommonEntityQuery[O](crud.TableName, dbExecutor, nil, nil),
-	})
-
-	// 通过ID获取班级
-	binding.GetBind(binder, &binding.SimpleBindItem[O]{
-		Path:         crud.DomainPath + "/get",
-		ResponseFunc: response.SendInfoResponse[O],
-		DTO:          crud.QueryByIDDTO,
-		Objects:      []domain.Object{crud.Entity},
-		ServiceFunc:  CommonEntityQueryByID[O](crud.TableName, dbExecutor, nil),
-	})
-}

+ 65 - 144
binding/entity_crud/transaction_service.go

@@ -4,18 +4,15 @@ import (
 	"git.sxidc.com/go-framework/baize/api"
 	"git.sxidc.com/go-framework/baize/binding"
 	"git.sxidc.com/go-framework/baize/binding/request"
-	"git.sxidc.com/go-framework/baize/binding/response"
 	"git.sxidc.com/go-framework/baize/domain"
 	"git.sxidc.com/go-framework/baize/infrastructure"
 	"git.sxidc.com/go-framework/baize/infrastructure/database"
 	"git.sxidc.com/go-framework/baize/infrastructure/database/sql"
-	"git.sxidc.com/go-framework/baize/tag/sql/sql_mapping"
 	"git.sxidc.com/go-tools/utils/strutils"
 	"git.sxidc.com/service-supports/fserr"
-	"reflect"
 )
 
-func CommonEntityCreate(tableName string, dbExecutor database.Executor, callbacks *Callbacks[string]) binding.ServiceFunc[string] {
+func CommonEntityCreateTx(tableName string, dbExecutor database.Executor, callbacks *Callbacks[string]) binding.ServiceFunc[string] {
 	return func(c *api.Context, dto request.DTO, objects []domain.Object, i *infrastructure.Infrastructure) (string, error) {
 		e, ok := objects[0].(domain.Entity)
 		if !ok {
@@ -24,28 +21,40 @@ func CommonEntityCreate(tableName string, dbExecutor database.Executor, callback
 
 		err := e.GenerateID()
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, "")
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, "")
 		}
 
-		err = callbackBeforeDBOperate(callbacks, e, dbExecutor)
-		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, "")
-		}
+		err = database.Transaction(dbExecutor, func(tx database.Executor) error {
+			err = callbackBeforeDBOperate(callbacks, e, tx)
+			if err != nil {
+				return err
+			}
 
-		err = database.InsertEntity(dbExecutor, tableName, e)
-		if err != nil {
-			if database.IsErrorDBRecordHasExist(err) {
-				err = fserr.New(e.DomainCNName() + "已存在")
+			err = database.InsertEntity(tx, tableName, e)
+			if err != nil {
+				if database.IsErrorDBRecordHasExist(err) {
+					err = fserr.New(e.DomainCNName() + "已存在")
+				}
+
+				return err
+			}
+
+			err = callbackAfterDBOperate(callbacks, e, tx)
+			if err != nil {
+				return err
 			}
 
-			return callbackOnError(callbacks, e, err, dbExecutor, "")
+			return nil
+		})
+		if err != nil {
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, "")
 		}
 
-		return callbackOnReturn(callbacks, e, dbExecutor, e.GetID())
+		return callbackOnSuccessReturn(callbacks, e, dbExecutor, e.GetID())
 	}
 }
 
-func CommonEntityDelete(tableName string, dbExecutor database.Executor, callbacks *Callbacks[any]) binding.ServiceFunc[any] {
+func CommonEntityDeleteTx(tableName string, dbExecutor database.Executor, callbacks *Callbacks[any]) binding.ServiceFunc[any] {
 	return func(c *api.Context, dto request.DTO, objects []domain.Object, i *infrastructure.Infrastructure) (any, error) {
 		e, ok := objects[0].(domain.Entity)
 		if !ok {
@@ -54,7 +63,7 @@ func CommonEntityDelete(tableName string, dbExecutor database.Executor, callback
 
 		if strutils.IsStringEmpty(e.GetID()) {
 			err := fserr.New("领域实体ID为空")
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
 		exist, err := database.CheckExist(dbExecutor, &sql.CheckExistExecuteParams{
@@ -62,29 +71,41 @@ func CommonEntityDelete(tableName string, dbExecutor database.Executor, callback
 			Conditions: sql.NewConditions().Equal(e.IDColumnName(), e.GetID()),
 		})
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
 		if !exist {
 			err := fserr.New(e.DomainCNName() + "不存在")
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
-		err = callbackBeforeDBOperate(callbacks, e, dbExecutor)
-		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
-		}
+		err = database.Transaction(dbExecutor, func(tx database.Executor) error {
+			err = callbackBeforeDBOperate(callbacks, e, tx)
+			if err != nil {
+				return err
+			}
+
+			err = database.DeleteEntity(tx, tableName, e)
+			if err != nil {
+				return err
+			}
 
-		err = database.DeleteEntity(dbExecutor, tableName, e)
+			err = callbackAfterDBOperate(callbacks, e, tx)
+			if err != nil {
+				return err
+			}
+
+			return nil
+		})
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
-		return callbackOnReturn(callbacks, e, dbExecutor, nil)
+		return callbackOnSuccessReturn(callbacks, e, dbExecutor, nil)
 	}
 }
 
-func CommonEntityUpdate(tableName string, dbExecutor database.Executor, callbacks *Callbacks[any]) binding.ServiceFunc[any] {
+func CommonEntityUpdateTx(tableName string, dbExecutor database.Executor, callbacks *Callbacks[any]) binding.ServiceFunc[any] {
 	return func(c *api.Context, dto request.DTO, objects []domain.Object, i *infrastructure.Infrastructure) (any, error) {
 		e, ok := objects[0].(domain.Entity)
 		if !ok {
@@ -93,7 +114,7 @@ func CommonEntityUpdate(tableName string, dbExecutor database.Executor, callback
 
 		if strutils.IsStringEmpty(e.GetID()) {
 			err := fserr.New("领域实体ID为空")
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
 		exist, err := database.CheckExist(dbExecutor, &sql.CheckExistExecuteParams{
@@ -101,136 +122,36 @@ func CommonEntityUpdate(tableName string, dbExecutor database.Executor, callback
 			Conditions: sql.NewConditions().Equal(e.IDColumnName(), e.GetID()),
 		})
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
 		if !exist {
 			err := fserr.New(e.DomainCNName() + "不存在")
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
-		err = callbackBeforeDBOperate(callbacks, e, dbExecutor)
-		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
-		}
-
-		err = database.UpdateEntity(dbExecutor, tableName, e)
-		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, nil)
-		}
-
-		return callbackOnReturn(callbacks, e, dbExecutor, nil)
-	}
-}
-
-func CommonEntityQuery[O any](tableName string, dbExecutor database.Executor, callbacks *Callbacks[response.InfosData[O]], conditionFieldCallback domain.ConditionFieldCallback) binding.ServiceFunc[response.InfosData[O]] {
-	return func(c *api.Context, dto request.DTO, objects []domain.Object, i *infrastructure.Infrastructure) (response.InfosData[O], error) {
-		queryDTO, ok := dto.(request.Query)
-		if !ok {
-			return response.InfosData[O]{}, fserr.New("DTO不是Query")
-		}
-
-		e, ok := objects[0].(domain.Entity)
-		if !ok {
-			return response.InfosData[O]{}, fserr.New("需要传递领域对象应该为实体")
-		}
-
-		conditions := sql.NewConditions()
-
-		fields, err := sql_mapping.DefaultUsage(e)
-		if err != nil {
-			return response.InfosData[O]{}, err
-		}
-
-		for _, field := range fields {
-			hasDeal := false
-			if conditionFieldCallback != nil {
-				hasDeal = conditionFieldCallback(conditions, field.FieldName, field.ColumnName, field.Value)
+		err = database.Transaction(dbExecutor, func(tx database.Executor) error {
+			err = callbackBeforeDBOperate(callbacks, e, tx)
+			if err != nil {
+				return err
 			}
 
-			if !hasDeal {
-				fieldValue := reflect.ValueOf(field.Value)
-				if !fieldValue.IsZero() {
-					conditions.Equal(field.ColumnName, field.Value)
-				}
+			err = database.UpdateEntity(tx, tableName, e)
+			if err != nil {
+				return err
 			}
-		}
-
-		err = callbackBeforeDBOperate(callbacks, e, dbExecutor)
-		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, response.InfosData[O]{})
-		}
-
-		results, totalCount, err := database.Query(dbExecutor, &sql.QueryExecuteParams{
-			TableName:  tableName,
-			Conditions: conditions,
-			PageNo:     queryDTO.GetPageNo(),
-			PageSize:   queryDTO.GetPageSize(),
-		})
-		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, response.InfosData[O]{})
-		}
-
-		infos := make([]O, 0)
-		err = sql.ParseSqlResult(results, &infos)
-		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, response.InfosData[O]{})
-		}
-
-		output := response.InfosData[O]{
-			Infos:      infos,
-			TotalCount: totalCount,
-			PageNo:     queryDTO.GetPageNo(),
-		}
-
-		return callbackOnReturn(callbacks, e, dbExecutor, output)
-	}
-}
-
-func CommonEntityQueryByID[O any](tableName string, dbExecutor database.Executor, callbacks *Callbacks[O]) binding.ServiceFunc[O] {
-	return func(c *api.Context, dto request.DTO, objects []domain.Object, i *infrastructure.Infrastructure) (O, error) {
-		var outputZero O
-		outputZeroValue := reflect.Zero(reflect.TypeOf(outputZero))
-		if outputZeroValue.Kind() == reflect.Pointer {
-			outputZeroValue.Set(reflect.New(outputZeroValue.Type().Elem()))
-		}
 
-		e, ok := objects[0].(domain.Entity)
-		if !ok {
-			return outputZero, fserr.New("需要传递领域对象应该为实体")
-		}
-
-		if strutils.IsStringEmpty(e.GetID()) {
-			err := fserr.New("领域实体ID为空")
-			return callbackOnError(callbacks, e, err, dbExecutor, outputZero)
-		}
-
-		err := callbackBeforeDBOperate(callbacks, e, dbExecutor)
-		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, outputZero)
-		}
+			err = callbackAfterDBOperate(callbacks, e, tx)
+			if err != nil {
+				return err
+			}
 
-		result, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{
-			TableName:  tableName,
-			Conditions: sql.NewConditions().Equal(e.IDColumnName(), e.GetID()),
+			return nil
 		})
 		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, outputZero)
-		}
-
-		var info O
-		var infoPointer any
-
-		infoPointer = &info
-		if outputZeroValue.Kind() == reflect.Pointer {
-			infoPointer = info
-		}
-
-		err = sql.ParseSqlResult(result, infoPointer)
-		if err != nil {
-			return callbackOnError(callbacks, e, err, dbExecutor, outputZero)
+			return callbackOnErrorReturn(callbacks, e, err, dbExecutor, nil)
 		}
 
-		return callbackOnReturn(callbacks, e, dbExecutor, info)
+		return callbackOnSuccessReturn(callbacks, e, dbExecutor, nil)
 	}
 }

+ 6 - 3
examples/binding/main.go

@@ -15,10 +15,10 @@ import (
 )
 
 // curl -X POST -H "Content-Type: application/json" -d '{"name":"test", "studentNum": 10}' "http://localhost:10100/test/v1/class/create"
-// curl -X PUT -H "Content-Type: application/json" -d '{"id":"6e3a9ec340124af6abe12fdbfd342580", "name":"test-new"}' "http://localhost:10100/test/v1/class/update"
+// curl -X PUT -H "Content-Type: application/json" -d '{"id":"f4fac01661704c5985bfc009f0fe6c3e", "name":"test-new"}' "http://localhost:10100/test/v1/class/update"
 // curl -X GET "http://localhost:10100/test/v1/class/query?name=test-new&pageNo=1&pageSize=1"
-// curl -X GET "http://localhost:10100/test/v1/class/get?id=6e3a9ec340124af6abe12fdbfd342580"
-// curl -X DELETE "http://localhost:10100/test/v1/class/6e3a9ec340124af6abe12fdbfd342580/delete"
+// curl -X GET "http://localhost:10100/test/v1/class/get?id=f4fac01661704c5985bfc009f0fe6c3e"
+// curl -X DELETE "http://localhost:10100/test/v1/class/f4fac01661704c5985bfc009f0fe6c3e/delete"
 
 type CreateClassJsonBody struct {
 	Name       string `json:"name" binding:"required" assign:"toField:Name"`
@@ -152,8 +152,11 @@ func main() {
 		DBExecutorType: binding.DBExecutorOperations,
 		DomainPath:     "/class",
 		CreateDTO:      &CreateClassJsonBody{},
+		CreateNeedTx:   true,
 		DeleteDTO:      &DeleteClassPathParams{},
+		DeleteNeedTx:   false,
 		UpdateDTO:      &UpdateClassJsonBody{},
+		UpdateNeedTx:   false,
 		QueryDTO:       &QueryClassesQueryParams{},
 		QueryByIDDTO:   &GetClassQueryParams{},
 	})

+ 6 - 3
examples/binding_ds/main.go

@@ -15,10 +15,10 @@ import (
 )
 
 // curl -X POST -H "Content-Type: application/json" -d '{"name":"test", "studentNum": 10}' "http://localhost:10100/test/v1/class/create"
-// curl -X PUT -H "Content-Type: application/json" -d '{"id":"76a386a4ff66448d9456843df848129c", "name":"test-new"}' "http://localhost:10100/test/v1/class/update"
+// curl -X PUT -H "Content-Type: application/json" -d '{"id":"9270f37031874ff985d34bff3ff5b23b", "name":"test-new"}' "http://localhost:10100/test/v1/class/update"
 // curl -X GET "http://localhost:10100/test/v1/class/query?name=test-new&pageNo=1&pageSize=1"
-// curl -X GET "http://localhost:10100/test/v1/class/get?id=76a386a4ff66448d9456843df848129c"
-// curl -X DELETE "http://localhost:10100/test/v1/class/76a386a4ff66448d9456843df848129c/delete"
+// curl -X GET "http://localhost:10100/test/v1/class/get?id=9270f37031874ff985d34bff3ff5b23b"
+// curl -X DELETE "http://localhost:10100/test/v1/class/9270f37031874ff985d34bff3ff5b23b/delete"
 
 type CreateClassJsonBody struct {
 	Name       string `json:"name" binding:"required" assign:"toField:Name"`
@@ -107,8 +107,11 @@ func main() {
 		DBExecutorType: binding.DBExecutorDataService,
 		DomainPath:     "/class",
 		CreateDTO:      &CreateClassJsonBody{},
+		CreateNeedTx:   false,
 		DeleteDTO:      &DeleteClassPathParams{},
+		DeleteNeedTx:   false,
 		UpdateDTO:      &UpdateClassJsonBody{},
+		UpdateNeedTx:   true,
 		QueryDTO:       &QueryClassesQueryParams{},
 		QueryByIDDTO:   &GetClassQueryParams{},
 	})