You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Diesel.rs中如何更新带有复合主键的列?

问题分析与修复方案

代码中的核心问题

  1. 语法错误:set(times_watched.eq(db_anime_ranking.times_watched += 1)) 里的 += 是 Rust 的赋值操作,不能直接作为 eq 的参数,这会导致编译失败。
  2. 逻辑重复:你已经在代码里执行了 db_anime_ranking.times_watched += 1,又在更新语句里再次自增,最终会导致计数多增加1次。
  3. 低效且有并发风险:先查询再更新的方式不仅多了一次数据库请求,还可能在并发场景下出现竞态条件(比如两个请求同时读取同一条数据,各自加1后写入,最终计数只加了1次)。

修复方案一:修正现有代码逻辑

如果一定要保留先查询的逻辑,只需去掉重复自增,修正语法错误:

for anime_ranking in new_anime_rankings {
    let mut db_anime_ranking: models::AnimeRanking = anime_rankings
        .find((anime_ranking.id, anime_ranking.genre_combo_id))
        .first(&mut connection)?;
    println!("{}", db_anime_ranking.id);

    db_anime_ranking.times_watched += 1;
    update(anime_rankings.filter((id.eq(anime_ranking.id), genre_combo_id.eq(anime_ranking.genre_combo_id))))
        .set(times_watched.eq(db_anime_ranking.times_watched)) // 直接传入更新后的值
        .execute(&mut connection)?;
}

修复方案二:数据库层面原子自增(推荐)

直接让数据库完成自增操作,无需先查询数据,既高效又能避免并发问题:

for anime_ranking in new_anime_rankings {
    update(anime_rankings.filter((id.eq(anime_ranking.id), genre_combo_id.eq(anime_ranking.genre_combo_id))))
        .set(times_watched.eq(times_watched + 1)) // 数据库层面直接自增,原子操作
        .execute(&mut connection)?;
}

这种方式利用数据库的原子性操作,确保即使多个请求同时更新同一条数据,计数也能正确累加。

内容的提问来源于stack exchange,提问作者asudox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 05:38:14