0

そのため、クレジットカードによる支払いを処理しており、支払いごとに一意の参照IDが必要です。MySQLを使用しています。

payments自動インクリメントの主キーID、processing_date、created_at、updated_atを持つテーブルがあります。私の問題は、支払いが処理されるまでこのレコードを保持できないことです(このプロセスはアプリケーションワークフローのために変更できません)。このため、支払いが処理されてからreference_id一意の制約を持つ列が追加されるまで主キーが存在しないため、主キーを単純に使用することはできません。

私の質問は、既存のテーブル列に基づいて(またはのようなものを使用して)連続番号をMAX(reference_id) + 1生成し、支払いを処理して(curlを使用して)、以前のテーブルに支払いレコードを挿入する信頼できる方法はありますか?reference_id一意性を確保しながら生成されます。基本的に、以前に生成されたreference_idをデータベースで予約します。

4

3 に答える 3

2

既存の列に基づいて作成しようとしないでください。2つのトランザクションを同時に実行すると、同じIDの2つのトランザクションになる可能性があります。

UUIDまたはタイムスタンプに基づいてください。

私は同様のシステムを持っており、トランザクションIDはMMDDYYHHMMSS+8桁の乱数です。これは少量のトランザクションでは問題なく、1秒間に2つ以上の重複トランザクションが発生する可能性はほとんどありません。

多くのゲートウェイはこれと同じスキームを使用します。

UUIDは、グローバルに一意であることを保証するため、最も安全です。

于 2011-02-23T00:07:42.493 に答える
1

ステータス/確認済みフラグとして、支払いテーブルに別の列を追加できます。支払いが開始されたら、値を挿入し、ステータスを「開始済み」(またはその他)に設定します。この方法で、自動生成されたIDを使用できます。

支払いが完了したら、フラグを「完了」に設定できます。支払いが拒否された場合は、行を削除します。

これを最適化するために、毎晩実行し、ステータスが「開始済み」で2日以上経過している行を削除するハウスキーピング手順を作成することもできます。

于 2011-02-23T00:28:53.367 に答える
1

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;

ロックが原因で、ロールバック後であっても、並行性に関する整合性の問題は発生しません。しかし、ユーザーは待たなければならないかもしれません。

于 2011-02-23T09:06:47.047 に答える