From 4e5c1287a6b78f62fd5e97bb141939552db085d5 Mon Sep 17 00:00:00 2001 From: iven Date: Wed, 3 Jun 2026 15:48:29 +0800 Subject: [PATCH] =?UTF-8?q?perf(diary):=20parent=5Fservice=20=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E8=BD=AF=E5=88=A0=E9=99=A4=E6=9B=BF=E4=BB=A3=E9=80=90?= =?UTF-8?q?=E6=9D=A1=20UPDATE=20=E2=80=94=208a-C03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - delete_child_data 改用单条 SQL UPDATE ... WHERE 批量软删除 - 1 次 SQL 替代 N 次逐条 UPDATE(从 O(N) 降到 O(1) 查询) - 移除不再需要的 TransactionTrait 导入 - 测试 80/80 通过 --- .../erp-diary/src/service/parent_service.rs | 56 ++++++++++--------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/crates/erp-diary/src/service/parent_service.rs b/crates/erp-diary/src/service/parent_service.rs index 5cd1a34..01d9708 100644 --- a/crates/erp-diary/src/service/parent_service.rs +++ b/crates/erp-diary/src/service/parent_service.rs @@ -2,8 +2,8 @@ use chrono::Utc; use sea_orm::{ - ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, PaginatorTrait, - QueryFilter, QueryOrder, Set, TransactionTrait, + ActiveModelTrait, ColumnTrait, ConnectionTrait, DatabaseConnection, EntityTrait, + PaginatorTrait, QueryFilter, QueryOrder, Set, }; use uuid::Uuid; @@ -272,7 +272,8 @@ impl ParentService { /// 删除孩子数据 — 软删除所有日记(PIPL 删除权) /// - /// 软删除孩子全部未删除的日记,逐条设置 deleted_at。 + /// 使用单条 SQL UPDATE 批量软删除,替代逐条更新。 + /// 性能: 1 次 SQL 替代 N 次 UPDATE。 /// 发布 `diary.parent.data_deleted` 事件记录操作。 pub async fn delete_child_data( tenant_id: Uuid, @@ -283,32 +284,33 @@ impl ParentService { ) -> DiaryResult { Self::verify_binding(tenant_id, parent_id, child_id, db).await?; - let journals = journal_entry::Entity::find() - .filter(journal_entry::Column::TenantId.eq(tenant_id)) - .filter(journal_entry::Column::AuthorId.eq(child_id)) - .filter(journal_entry::Column::DeletedAt.is_null()) - .all(db) - .await?; - - let count = journals.len(); let now = Utc::now(); - // 事务:软删除所有日记(PIPL 删除权 — 原子操作,避免部分删除) - db.transaction::<_, (), DiaryError>(|txn| { - Box::pin(async move { - for journal in journals { - let current_version = journal.version; - let mut active: journal_entry::ActiveModel = journal.into(); - active.deleted_at = Set(Some(now)); - active.updated_at = Set(now); - active.updated_by = Set(parent_id); - active.version = Set(current_version + 1); - active.update(txn).await?; - } - Ok(()) - }) - }) - .await?; + // 批量软删除 — 单条 SQL 替代逐条 UPDATE(性能优化 8a-C03) + let sql = r#" + UPDATE journal_entries + SET deleted_at = $1, + updated_at = $1, + updated_by = $2, + version = version + 1 + WHERE tenant_id = $3 + AND author_id = $4 + AND deleted_at IS NULL + "#; + + let stmt = sea_orm::Statement::from_sql_and_values( + sea_orm::DatabaseBackend::Postgres, + sql, + [ + now.into(), + parent_id.into(), + tenant_id.into(), + child_id.into(), + ], + ); + + let result = db.execute(stmt).await?; + let count = result.rows_affected() as usize; event_bus .publish(