#14260·hyperswitch

[BUG] 重放无法重现并发地址更新或 mandate.created_at

作者: maverox创建于 2026年9月16日更新于 2026年9月16日
  1. mandate.created_at 由数据库决定 MandateNew.created_atOption<PrimitiveDateTime>,而 mandate 表中包含 DEFAULT now()diesel_models/src/mandate.rs 中有一个回退机制,看起来似乎涵盖了这一点:
rust
impl From<&MandateNew> for Mandate {
    created_at: mandate_new.created_at.unwrap_or_else(common_utils::date_time::now),

但在关键的路径上,它并没有涵盖这一点。router/src/db/mandate.rs 根据存储方案进行分支:

rust
MerchantStorageScheme::PostgresOnly => mandate.insert(&conn),  // MandateNew 直接传递给 diesel
MerchantStorageScheme::RedisKv      => { /* builds Mandate::from(&mandate), running the unwrap_or_else */ }

MandateNew::insert() 调用 generics::generic_insert(conn, self),将 MandateNew 直接传递给 diesel。From impl — 以及其 unwrap_or_else — 仅在 Redis KV 分支中运行。因此,使用 KV 存储方案的商家获得的是应用程序选择的时间戳,而使用 PostgresOnly 存储方案的商家获得的是 Postgres 选择的时间戳,这来自相同的代码。在 Postgres 路径上,该值是数据库中在语句离开进程后读取的时钟,应用程序侧的任何仪表都无法观察到,也无法通过重放重现。一个存储路径内的回退机制并不是类型的默认值。

内容来源: juspay/hyperswitch