perf(diary): parent_service 批量软删除替代逐条 UPDATE — 8a-C03

- delete_child_data 改用单条 SQL UPDATE ... WHERE 批量软删除
- 1 次 SQL 替代 N 次逐条 UPDATE(从 O(N) 降到 O(1) 查询)
- 移除不再需要的 TransactionTrait 导入
- 测试 80/80 通过
This commit is contained in:
iven
2026-06-03 15:48:29 +08:00
parent 3258acaa77
commit 4e5c1287a6

View File

@@ -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<usize> {
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(