【问题标题】:Can you guarantee unique sequential numbers in mysql你能保证mysql中唯一的序号吗
【发布时间】:2011-02-23 00:03:16
【问题描述】:

因此,我们正在处理信用卡付款,并且每次付款都需要一个唯一的参考 ID。我们正在使用 MySQL。

有一个payments 表,它有一个自动递增的主键 id、processing_date、created_at、updated_at。我的问题是,在处理付款之前无法保留此记录(由于应用程序工作流程,此过程无法更改)。因此,我们不能简单地使用主键,因为在处理付款之前它不会存在,并且已经添加了具有唯一约束的 reference_id 列。

我的问题是,是否有一种可靠的方法可以根据现有表列(即使用 MAX(reference_id) + 1 之类的东西)生成顺序(或接近)数字,处理付款(使用 curl)然后插入付款记录与先前生成的reference_id 一起放入表中,同时确保唯一性。本质上是在数据库中保留先前生成的reference_id。

【问题讨论】:

    标签: mysql uniqueidentifier unique-constraint sequential


    【解决方案1】:

    不要试图以现有列为基础。如果您同时进行 2 笔交易,您最终可能会获得 2 笔具有相同 ID 的交易。

    基于UUID 或时间戳。

    我有一个类似的系统,交易 ID 是 MMDDYYHHMMSS + 8 位随机数。这对于少量交易来说是可以的,并且不太可能在 1 秒内出现 2 个或更多重复交易。

    许多网关使用相同的方案。

    UUID 是最安全的,因为它保证它是全球唯一的。

    【讨论】:

    • 生成唯一编号不是问题,而是确保它们是连续的。序列中可以有跳过的元素(有原因)。这可能排除了任何使用随机数的可能性。
    【解决方案2】:

    您可以在付款表中添加另一列作为状态/已确认标志。付款开始时,您插入值并将状态设置为“已开始”(或其他),这样您就可以使用自动生成的 ID。

    付款完成后,您可以将标志设置为“已完成”。如果付款被拒绝,请删除该行。

    为了优化这一点,您还可以创建一个每天晚上运行的内务处理程序,并删除状态为“已启动”且超过 2 天或类似情况的行。

    【讨论】:

    • 这类似于我们目前正在考虑的方法。
    【解决方案3】:

    您需要一个额外的表作为 reference_id 并在每次需要新数字时更新此值。将所有内容包装在事务中,您就可以省钱了。 MySQL 变量的使用使 SQL 中的事情变得非常简单:

    CREATE TABLE reference_id(
    id INT NOT NULL
    );
    INSERT INTO reference_id (id) VALUES (1);
    
    REVOKE INSERT, DELETE, TRUNCATE FROM [all users];
    

    --真正的工作:

    BEGIN;
    SET @i = 0;
    SELECT id + 1 INTO @i FROM reference_id FOR UPDATE;
    UPDATE reference_id SET id = @i;
    INSERT INTO other_table(ref_id, content) VALUES(@i, 'bla');
    COMMIT;
    

    由于有了锁,您不会遇到并发完整性问题,即使在 ROLLBACK 之后也不会。但用户可能需要等待。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-13
      相关资源
      最近更新 更多