Coze源码分析-资源库-删除数据库-后端源码-领域服务/数据访问层

4. 领域服务层

数据库领域服务层架构

数据库领域服务层是Coze Studio中处理数据库业务逻辑的核心层,负责数据库资源的删除、管理和业务规则实现。该层采用领域驱动设计(DDD)模式,将业务逻辑与数据访问分离,确保代码的可维护性和可扩展性。

数据库领域服务接口定义

数据库领域服务接口定义了数据库管理的核心业务能力,包括数据库资源的完整生命周期管理。

go 复制代码
type DatabaseService interface {
	// 删除数据库
	DeleteDatabase(ctx context.Context, req *DeleteDatabaseRequest) error
	
	// 其他数据库管理方法
	CreateDatabase(ctx context.Context, req *CreateDatabaseRequest) (*CreateDatabaseResponse, error)
	GetDatabase(ctx context.Context, req *GetDatabaseRequest) (*GetDatabaseResponse, error)
	UpdateDatabase(ctx context.Context, req *UpdateDatabaseRequest) error
}

核心接口功能

  1. 数据库资源管理:创建、获取、更新、删除用户自定义的数据库资源
  2. 删除操作核心:DeleteDatabase方法是删除数据库的核心业务接口
  3. 事务管理:确保数据库删除操作的原子性和一致性
  4. 业务规则封装:封装数据库相关的业务逻辑和验证规则
  5. 数据完整性保障:确保数据库及其关联数据的完整删除
数据库领域服务实现

文件位置:backend/domain/memory/database/service/database_impl.go

数据库服务实现类包含了所有数据库相关业务逻辑的具体实现,负责处理数据库删除的核心业务逻辑,包括在线库和草稿库的同时删除。

go 复制代码
func (d databaseService) DeleteDatabase(ctx context.Context, req *DeleteDatabaseRequest) error {
	onlineInfo, err := d.onlineDAO.Get(ctx, req.ID)
	if err != nil {
		return fmt.Errorf("get online database info failed: %v", err)
	}

	draftInfo, err := d.draftDAO.Get(ctx, onlineInfo.GetDraftID())
	if err != nil {
		return fmt.Errorf("get draft database info failed: %v", err)
	}

	tx := query.Use(d.db).Begin()
	if tx.Error != nil {
		return fmt.Errorf("start transaction failed, %v", tx.Error)
	}

	defer func() {
		if r := recover(); r != nil {
			e := tx.Rollback()
			if e != nil {
				logs.CtxErrorf(ctx, "rollback failed, err=%v", e)
			}

			err = fmt.Errorf("catch panic: %v\nstack=%s", r, string(debug.Stack()))
			return
		}

		if err != nil {
			e := tx.Rollback()
			if e != nil {
				logs.CtxErrorf(ctx, "rollback failed, err=%v", e)
			}
		}
	}()

	err = d.draftDAO.DeleteWithTX(ctx, tx, draftInfo.ID)
	if err != nil {
		return fmt.Errorf("delete draft database info failed: %v", err)
	}

	err = d.onlineDAO.DeleteWithTX(ctx, tx, onlineInfo.ID)
	if err != nil {
		return fmt.Errorf("delete online database info failed: %v", err)
	}

	err = tx.Commit()
	if err != nil {
		return fmt.Errorf("commit transaction failed: %v", err)
	}

	// delete draft physical table
	if draftInfo.ActualTableName != "" {
		_, err = d.rdb.DropTable(ctx, &rdb.DropTableRequest{
			TableName: draftInfo.ActualTableName,
		})
		// 错误处理...
	}

	// delete online physical table
	if onlineInfo.ActualTableName != "" {
		_, err = d.rdb.DropTable(ctx, &rdb.DropTableRequest{
			TableName: onlineInfo.ActualTableName,
		})
		// 错误处理...
	}

	return nil
}

删除操作实现特点

  1. 事务保障:使用数据库事务确保删除操作的原子性和一致性
  2. 完整删除:同时删除在线库和草稿库的元数据和物理表
  3. 异常处理:完善的panic恢复和事务回滚机制
  4. 资源清理:删除数据库相关的物理表资源
  5. 错误包装:详细的错误信息,便于问题定位和调试

DeleteDatabase方法详解

  • 参数:接收DeleteDatabaseRequest结构体,包含数据库ID
  • 处理流程
    1. 获取在线数据库信息
    2. 获取对应草稿数据库信息
    3. 开启事务进行原子操作
    4. 删除草稿数据库信息
    5. 删除在线数据库信息
    6. 提交事务
    7. 删除物理表资源
  • 错误处理:每个步骤都有详细的错误捕获和包装
数据库实体定义

数据库实体定义了数据库资源的核心数据结构,包含了数据库的所有关键属性。

go 复制代码
type Database struct {
	ID             int64         // 数据库唯一标识
	AppID          int64         // 所属应用ID
	SpaceID        int64         // 所属空间ID,支持多租户隔离
	CreatorID      int64         // 创建者ID
	TableName      string        // 表名
	FieldList      []*FieldItem  // 字段列表
	ActualTableName string       // 实际物理表名
	DraftID        *int64        // 草稿ID
	RwMode         BotTableRWMode // 读写模式
	Status         BotTableStatus // 状态
	CreatedAt      int64         // 创建时间戳
	UpdatedAt      int64         // 更新时间戳
}

实体设计特点

  1. 基础信息:包含ID、应用ID、空间ID等基本属性
  2. 表结构定义:通过FieldList定义数据库表结构
  3. 多租户支持:SpaceID字段支持多租户和空间隔离
  4. 创建者管理:CreatorID字段支持数据库所有权管理
  5. 状态管理:Status字段支持数据库的生命周期管理
  6. 物理映射:ActualTableName字段记录实际物理表名
  7. 草稿关联:DraftID字段关联对应的草稿版本
  8. 读写控制:RwMode字段控制数据库的读写权限
  9. 时间追踪:CreatedAt和UpdatedAt支持时间追踪和审计

5. 数据访问层

5.1 仓储接口定义

数据库仓储接口

数据库仓储接口定义了数据库资源的持久化操作能力,包括数据库的增删改查等核心功能。

go 复制代码
type DatabaseRepository interface {
	// DeleteDatabase 删除数据库
	DeleteDatabase(ctx context.Context, id int64) error
	// GetDatabase 获取数据库信息
	GetDatabase(ctx context.Context, id int64) (*DatabaseInfo, error)
	// 其他CRUD方法...
}

删除方法特点

  • 事务删除:DeleteDatabase方法支持事务操作,确保数据一致性
  • 上下文支持:支持context.Context进行请求链路追踪
  • 错误处理:返回error类型,便于上层进行错误处理
  • ID定位:通过唯一id精确定位要删除的数据库资源

5.2 数据访问对象(DAO)

数据库删除的具体实现

数据库删除操作涉及在线库和草稿库的同步删除,需要通过事务确保数据一致性:

go 复制代码
func (d *databaseRepoImpl) DeleteDatabase(ctx context.Context, id int64) (err error) {
	onlineInfo, err := d.onlineDAO.Get(ctx, id)
	if err != nil {
		return fmt.Errorf("get online database info failed: %v", err)
	}

	draftInfo, err := d.draftDAO.Get(ctx, onlineInfo.GetDraftID())
	if err != nil {
		return fmt.Errorf("get draft database info failed: %v", err)
	}

	tx := query.Use(d.db).Begin()
	if tx.Error != nil {
		return fmt.Errorf("start transaction failed, %v", tx.Error)
	}

	defer func() {
		if r := recover(); r != nil {
			e := tx.Rollback()
			if e != nil {
				logs.CtxErrorf(ctx, "rollback failed, err=%v", e)
			}

			err = fmt.Errorf("catch panic: %v\nstack=%s", r, string(debug.Stack()))
			return
		}

		if err != nil {
			e := tx.Rollback()
			if e != nil {
				logs.CtxErrorf(ctx, "rollback failed, err=%v", e)
			}
		}
	}()

	err = d.draftDAO.DeleteWithTX(ctx, tx, draftInfo.ID)
	if err != nil {
		return fmt.Errorf("delete draft database info failed: %v", err)
	}

	err = d.onlineDAO.DeleteWithTX(ctx, tx, onlineInfo.ID)
	if err != nil {
		return fmt.Errorf("delete online database info failed: %v", err)
	}

	err = tx.Commit()
	if err != nil {
		return fmt.Errorf("commit transaction failed: %v", err)
	}

	// 删除物理表资源
	if draftInfo.ActualTableName != "" {
		_, err = d.rdb.DropTable(ctx, &rdb.DropTableRequest{
			TableName: draftInfo.ActualTableName,
		})
		// 错误处理...
	}

	if onlineInfo.ActualTableName != "" {
		_, err = d.rdb.DropTable(ctx, &rdb.DropTableRequest{
			TableName: onlineInfo.ActualTableName,
		})
		// 错误处理...
	}

	return nil
}

删除操作的关键特点

  1. 事务保证:使用数据库事务确保所有删除操作的原子性
  2. 完整删除:同时删除在线库和草稿库的元数据和物理表
  3. 异常处理:完善的panic恢复和事务回滚机制
  4. 资源清理:删除数据库相关的物理表资源
  5. 错误包装:详细的错误信息,便于问题定位和调试

删除涉及的数据表

  • bot_table_info:数据库元数据表
  • bot_table_info_draft:数据库草稿表
  • 物理表:实际存储数据的物理表
DatabaseDAO结构体

DatabaseDAO是数据库数据访问的具体实现,负责与数据库进行交互,处理数据库资源的持久化操作。

go 复制代码
package dal

import (
	"context"
	"fmt"

	"gorm.io/gorm"

	"github.com/coze-dev/coze-studio/backend/infra/contract/idgen"
)

type DatabaseDAO struct {
	db *gorm.DB
	idGen idgen.IDGenerator
}

func NewDatabaseDAO(db *gorm.DB, generator idgen.IDGenerator) *DatabaseDAO {
	return &DatabaseDAO{
		db: db,
		idGen: generator,
	}
}
数据库删除操作实现

删除数据库记录

go 复制代码
func (d *DatabaseDAO) DeleteWithTX(ctx context.Context, tx *gorm.DB, id int64) (err error) {
	result := tx.WithContext(ctx).Where("id = ?", id).Delete(&DatabaseInfo{})
	if result.Error != nil {
		return fmt.Errorf("delete database in transaction failed: %v", result.Error)
	}
	
	if result.RowsAffected == 0 {
		return fmt.Errorf("database not found with id: %d", id)
	}
	
	return nil
}

获取数据库信息

go 复制代码
func (d *DatabaseDAO) Get(ctx context.Context, id int64) (*DatabaseInfo, error) {
	var info DatabaseInfo
	result := d.db.WithContext(ctx).Where("id = ?", id).First(&info)
	if result.Error != nil {
		return nil, fmt.Errorf("get database failed: %v", result.Error)
	}
	return &info, nil
}
数据转换方法

数据库实体与数据模型转换

go 复制代码
func (d *DatabaseDAO) databaseInfoDO2PO(database *entity.DatabaseInfo) *model.DatabaseInfo {
	fieldListJSON, _ := json.Marshal(database.FieldList)
	return &model.DatabaseInfo{
		ID:             database.ID,
		AppID:          database.AppID,
		SpaceID:        database.SpaceID,
		CreatorID:      database.CreatorID,
		TableName:      database.TableName,
		FieldList:      string(fieldListJSON),
		ActualTableName: database.ActualTableName,
		DraftID:        database.DraftID,
		RwMode:         int32(database.RwMode),
		Status:         int32(database.Status),
	}
}

数据模型转实体

go 复制代码
type databaseInfoPO model.DatabaseInfo

func (d databaseInfoPO) ToDO() *entity.DatabaseInfo {
	var fieldList []*entity.FieldItem
	_ = json.Unmarshal([]byte(d.FieldList), &fieldList)
	
	database := &entity.DatabaseInfo{
		ID:             d.ID,
		AppID:          d.AppID,
		SpaceID:        d.SpaceID,
		CreatorID:      d.CreatorID,
		TableName:      d.TableName,
		FieldList:      fieldList,
		ActualTableName: d.ActualTableName,
		DraftID:        d.DraftID,
		RwMode:         entity.BotTableRWMode(d.RwMode),
		Status:         entity.BotTableStatus(d.Status),
		CreatedAt:      d.CreatedAt,
		UpdatedAt:      d.UpdatedAt,
	}
	return database
}

删除操作特点

  1. 事务删除:DeleteWithTX方法支持事务操作,确保数据一致性
  2. 精确定位:通过id精确定位要删除的数据库资源
  3. 结果验证:验证删除操作是否实际影响了数据行
  4. 物理删除:执行物理删除操作,从数据库中彻底移除记录
  5. 资源清理:同时清理物理表资源,避免资源泄漏

删除数据库的完整数据访问流程

在删除数据库的场景中,数据访问层的操作流程如下:

  1. 获取在线库信息:查询在线数据库的元数据信息
  2. 获取草稿库信息:根据在线库关联的DraftID查询草稿库信息
  3. 事务开始:开启数据库事务,确保删除操作的原子性
  4. 删除草稿库:在事务中删除草稿库记录
  5. 删除在线库:在事务中删除在线库记录
  6. 事务提交:所有删除操作成功后提交事务
  7. 删除物理表:提交事务后,删除相关的物理表资源
  8. 错误回滚:任何操作失败时回滚事务,保证数据一致性

这种设计确保了删除操作的安全性、可靠性和数据完整性。

数据访问层删除操作总结

删除数据库在数据访问层的实现具有以下特点:

  1. 事务保证:所有元数据删除操作在事务中执行,确保数据一致性
  2. 完整删除:同时删除在线库、草稿库和物理表资源
  3. 验证机制:验证删除操作是否成功,确保资源确实被删除
  4. 错误处理:完善的错误处理和事务回滚机制
  5. 资源清理:彻底清理相关资源,避免资源泄漏
  6. 性能优化:通过精确的WHERE条件,确保删除操作的高效执行

5.3 数据库数据模型

DatabaseInfo数据模型

数据库数据模型定义了数据库资源在数据库中的存储结构,使用GORM标签进行ORM映射。

go 复制代码
// DatabaseInfo 数据库信息模型
type DatabaseInfo struct {
	ID             int64  `gorm:"column:id;primaryKey;autoIncrement;comment:数据库ID" json:"id"`
	AppID          int64  `gorm:"column:app_id;not null;index:idx_appid;comment:应用ID" json:"app_id"`
	SpaceID        int64  `gorm:"column:space_id;not null;index:idx_spaceid;comment:空间ID" json:"space_id"`
	CreatorID      int64  `gorm:"column:creator_id;not null;index:idx_creatorid;comment:创建者ID" json:"creator_id"`
	TableName      string `gorm:"column:table_name;not null;type:varchar(100);comment:表名" json:"table_name"`
	FieldList      string `gorm:"column:field_list;type:text;comment:字段列表" json:"field_list"`
	ActualTableName string `gorm:"column:actual_table_name;type:varchar(255);comment:实际表名" json:"actual_table_name"`
	DraftID        *int64 `gorm:"column:draft_id;index:idx_draftid;comment:草稿ID" json:"draft_id"`
	RwMode         int32  `gorm:"column:rw_mode;default:0;comment:读写模式" json:"rw_mode"`
	Status         int32  `gorm:"column:status;default:0;comment:状态" json:"status"`
	CreatedAt      int64  `gorm:"column:created_at;not null;autoCreateTime;comment:创建时间" json:"created_at"`
	UpdatedAt      int64  `gorm:"column:updated_at;not null;autoUpdateTime;comment:更新时间" json:"updated_at"`
}

// TableName 指定表名
func (*DatabaseInfo) TableName() string {
	return "bot_table_info"
}

删除操作中的模型特点

  1. 主键定位:ID字段作为主键,是删除操作的核心定位字段,确保精确删除
  2. 索引优化:为AppID、SpaceID、CreatorID、DraftID字段建立索引,提高查询效率
  3. 关联字段:DraftID字段关联在线库和草稿库,支持级联删除
  4. 物理映射:ActualTableName字段记录实际物理表名,支持物理资源清理
  5. 类型约束:对字符串类型设置长度限制,确保数据完整性
  6. 默认值设置:为RwMode和Status字段设置默认值
  7. 时间戳自动管理:使用autoCreateTime和autoUpdateTime自动管理时间戳
  8. JSON序列化:通过json标签支持JSON序列化,便于API响应和日志记录

5.4 GORM生成的查询接口

GORM框架为数据库数据模型生成了丰富的查询接口,支持各种查询和操作场景。

go 复制代码
// 根据ID查询
func (d *DatabaseDAO) GetByID(ctx context.Context, id int64) (*DatabaseInfo, error) {
	var info DatabaseInfo
	result := d.db.WithContext(ctx).First(&info, "id = ?", id)
	if result.Error != nil {
		return nil, result.Error
	}
	return &info, nil
}

// 条件查询
func (d *DatabaseDAO) ListByCondition(ctx context.Context, condition map[string]interface{}, page, pageSize int) ([]*DatabaseInfo, error) {
	var infos []*DatabaseInfo
	query := d.db.WithContext(ctx)
	
	// 添加查询条件
	for key, value := range condition {
		query = query.Where(key, value)
	}
	
	// 分页查询
	result := query.Offset((page - 1) * pageSize).Limit(pageSize).Find(&infos)
	if result.Error != nil {
		return nil, result.Error
	}
	
	return infos, nil
}
复制代码
#### 查询接口定义
```go
type IWorkflowDraftDo interface {
	gen.SubQuery
	Debug() IWorkflowDraftDo
	WithContext(ctx context.Context) IWorkflowDraftDo
	WithResult(fc func(tx gen.Dao)) gen.ResultInfo
	ReplaceDB(db *gorm.DB)
	ReadDB() IWorkflowDraftDo
	WriteDB() IWorkflowDraftDo
	// 删除操作相关方法
	Delete(conds ...gen.Condition) (gen.ResultInfo, error)
	Where(conds ...gen.Condition) IWorkflowDraftDo
	......
}

删除操作相关接口特点

  1. Delete方法:提供类型安全的删除操作,支持条件删除
  2. Where条件:支持复杂的删除条件构建,确保精确删除
  3. 上下文支持:WithContext方法支持请求上下文传递
  4. 事务支持:支持在事务中执行删除操作,确保数据一致性
  5. 调试支持:Debug方法便于删除操作的SQL调试和优化
5.5 统一查询入口

文件位置:backend\domain\workflow\internal\dal\query\gen.go

该文件为删除工作流操作提供了统一的查询入口和事务支持,确保删除操作的一致性和可靠性。

核心代码:

go 复制代码
// Code generated by gorm.io/gen. DO NOT EDIT.

package query

import (
	"context"
	"database/sql"

	"gorm.io/gorm"

	"gorm.io/gen"

	"gorm.io/plugin/dbresolver"
)

var (
	Q            = new(Query)
	WorkflowDraft *workflowDraft
)

func SetDefault(db *gorm.DB, opts ...gen.DOOption) {
	*Q = *Use(db, opts...)
	WorkflowDraft = &Q.WorkflowDraft
}

func Use(db *gorm.DB, opts ...gen.DOOption) *Query {
	return &Query{
		db:          db,
		PluginDraft: newPluginDraft(db, opts...),
		ToolDraft:   newToolDraft(db, opts...),
	}
}

type Query struct {
	db *gorm.DB

	WorkflowDraft workflowDraft
}

func (q *Query) Available() bool { return q.db != nil }

func (q *Query) clone(db *gorm.DB) *Query {
	return &Query{
		db:          db,
		WorkflowDraft: q.WorkflowDraft.clone(db),
	}
}

func (q *Query) ReadDB() *Query {
	return q.ReplaceDB(q.db.Clauses(dbresolver.Read))
}

func (q *Query) WriteDB() *Query {
	return q.ReplaceDB(q.db.Clauses(dbresolver.Write))
}

func (q *Query) ReplaceDB(db *gorm.DB) *Query {
	return &Query{
		db:          db,
		WorkflowDraft: q.WorkflowDraft.replaceDB(db),
	}
}

type queryCtx struct {
	WorkflowDraft IWorkflowDraftDo
}

func (q *Query) WithContext(ctx context.Context) *queryCtx {
	return &queryCtx{
		WorkflowDraft: q.WorkflowDraft.WithContext(ctx),
	}
}

func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error {
	return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...)
}

func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx {
	tx := q.db.Begin(opts...)
	return &QueryTx{Query: q.clone(tx), Error: tx.Error}
}

type QueryTx struct {
	*Query
	Error error
}

func (q *QueryTx) Commit() error {
	return q.db.Commit().Error
}

func (q *QueryTx) Rollback() error {
	return q.db.Rollback().Error
}

func (q *QueryTx) SavePoint(name string) error {
	return q.db.SavePoint(name).Error
}

func (q *QueryTx) RollbackTo(name string) error {
	return q.db.RollbackTo(name).Error
}

删除操作查询入口特点

  1. 全局查询对象:提供全局的WorkflowDraft查询对象,便于删除操作的统一管理
  2. 事务支持:Transaction方法支持在事务中执行删除操作,确保数据一致性
  3. 读写分离:ReadDB和WriteDB方法支持数据库读写分离,删除操作使用WriteDB
  4. 上下文传递:WithContext方法支持请求上下文在删除操作中的传递
  5. 数据库切换:ReplaceDB方法支持动态切换数据库连接,便于多环境部署
  6. 事务管理:Begin、Commit、Rollback等方法提供完整的事务管理能力

5.6 数据访问层删除操作架构总结

删除工作流在数据访问层的实现体现了现代Go应用的最佳实践:

技术特点

  1. 类型安全:使用GORM Gen生成类型安全的查询接口,避免SQL注入和类型错误
  2. 分层设计:Repository接口抽象数据访问,DAO实现具体的数据库操作
  3. 错误处理:统一的错误码包装机制,便于上层进行错误分类和处理
  4. 事务支持:完整的事务支持,确保删除操作的原子性
  5. 性能优化:精确的WHERE条件和索引利用,确保删除操作的高效执行

安全保障

  1. 权限验证:通过OwnerID字段确保只有工作流所有者可以删除自己的工作流
  2. 存在性检查:删除前验证工作流是否存在,避免无效删除
  3. 物理删除:彻底从数据库中移除记录,确保数据清理的完整性
  4. 审计追踪:完整的时间戳记录,支持删除操作的审计和追踪

删除操作流程

  1. 接口调用:上层通过Repository接口调用DeleteDraftWorkflow方法
  2. 事务开启:开启数据库事务确保操作的原子性
  3. 删除操作:删除工作流数据
  4. 事务提交:删除操作成功后提交事务
  5. 错误处理:任何步骤失败都会回滚事务并返回错误

这种设计确保了删除工作流操作的安全性、可靠性和高性能,为上层业务逻辑提供了坚实的数据访问基础。

数据模型与查询文件依赖关系
复制代码
数据库表结构 (schema.sql)(workflow_draft表)
    ↓    gen_orm_query.go
模型文件 (model/workflow_draft.gen.go) - 生成模型
    ↓
查询文件 (query/workflow_draft.gen.go) - 依赖对应模型
    ↓
统一入口 (query/gen.go) - 依赖所有查询文件

数据访问层架构总结

分层架构

复制代码
业务服务层 (Service)
       ↓
仓储接口层 (Repository Interface)
       ↓
数据访问层 (DAO Implementation)
       ↓
GORM查询层 (Generated Query)
       ↓
数据模型层 (Generated Model)
       ↓
数据库层 (MySQL)

删除工作流在数据访问层的完整流程

  1. 接口定义WorkflowRepository.DeleteDraftWorkflow(ctx, ID) 定义删除操作契约
  2. DAO实现WorkflowDraftDAO.DeleteWithTX(tx, ID) 实现具体删除逻辑
  3. 事务管理:使用事务确保工作流数据的一致性删除
  4. 删除操作:执行工作流数据的删除操作
  5. 错误处理:包装删除异常为统一错误码
  6. 结果返回:删除成功返回nil,失败返回包装后的错误

设计优势

  1. 接口抽象:通过Repository接口实现数据访问的抽象化
  2. 代码生成:使用GORM Gen自动生成类型安全的查询代码
  3. 错误处理:统一的错误包装和处理机制
  4. 事务支持:通过context传递支持数据库事务
  5. 删除安全:通过ID精确定位,避免误删除操作
  6. 性能优化:合理的索引设计和查询优化
  7. 可测试性:清晰的分层结构便于单元测试
  8. 可维护性:代码生成减少手工编写,降低维护成本
  9. 单一职责:每个DAO类专注于单一实体的数据访问操作

删除操作的技术特点

  • 物理删除:当前实现为物理删除,直接从数据库中移除记录
  • 事务操作:使用数据库事务确保工作流数据的一致性删除
  • 索引优化:基于主键ID的删除操作,具有最佳的查询性能
  • 错误分类:通过错误码区分不同类型的删除异常
  • 审计支持:可通过数据库日志追踪删除操作的执行情况
相关推荐
cqsztech2 小时前
oracle linux 10 +pg18 源码安装要点
linux·数据库·oracle
健康平安的活着2 小时前
spring事务传播级别的实操案例2
数据库
安审若无2 小时前
Oracle 闪回过期后的解决方法
数据库·oracle
Navicat中国2 小时前
Navicat 技术指引 | KingbaseES 逆向工程与正向工程
数据库·database·navicat·建模·金仓·kingbasees
奥尔特星云大使2 小时前
ALTER 与 UPDATE、DROP 与 DELETE区别
linux·运维·数据库·mysql
六月闻君3 小时前
MySQLdump 常用参数说明
数据库·mysql
无敌最俊朗@5 小时前
C++ 序列容器深度解析:vector、deque 与 list
开发语言·数据结构·数据库·c++·qt·list
喃寻~5 小时前
java面试
数据库·sql·mysql
小池先生6 小时前
activemq延迟消息变成实时收到了?
linux·数据库·activemq