2017-03-06 52 views
0

私は会社の受領番号を生成するために使用されるpostgresにデータベーステーブルを持っています。テーブルは、投稿の後に行が記録されたときに挿入されるreceipt_numberという名前の列を持っています。最後の領収書番号を確認し、次の領収書番号を得るために1ずつインクリメントします。問題は、2人のクライアントが同時に支払うとすると、2行が記録されますが、同じ領収書番号があります。 。postgresデータベーステーブルの重複するエントリを制御する方法

複数のクライアントが同時に支払いを行う場合にのみ、偶然にも...その原因が何であるかの任意のアイデア..事前に

おかげで

+0

テーブルにプライマリキーがありません –

+0

"last receipt_number"はどのようにチェックしますか?それが単純な 'max()'ならば、決して動作しません。あなたは番号の隙間に住むことができますか?次に、シーケンスを使用します。 –

+0

私は前に使用したPKを持っていますが、突然それが連続した順序ではなく番号を飛び越し始めたので、私は別のcolumnを導入することにしました。私は、別のテーブルを持っている私は、レシートテーブルに新しいレコードを挿入する前にcurrent_receipt_numberを呼び出す1つずつインクリメントし、現在の番号に更新して次のエントリの準備を整える – user6781731

答えて

0

これは、同時アクセスによるものです。イベントが同時に2回発生すると、両方のインスタンスが最大値を取得してから、もう一方が保存されるため、最大値は同じになります。考えられる解決策は、列をserialにすることです。それがオプションでない場合は、サーバー側でイベントキューを持つことができます。新しいレコードを挿入する代わりに、挿入する代わりにキューを追加することもできます。一方、cronジョブまたはハートビートジョブはキューを定期的にチェックし、空でない場合はコマンドを順次実行します。

+0

あなたのコメントから、私はそれをチェックしようとしているので、私はシリアルに既存の列を変更することはできないようです。 – user6781731

+0

@ user6781731これは、データが重複しているためです。変更については、こちらをご覧くださいhttp://stackoverflow.com/questions/27307835/how-to-convert-primary-key-from-integer-to-serial –

+0

@ user6781731また、ギャップがあるかもしれません。私はあなたがオンラインアプリケーションを停止し、列のシリアルバージョンを持っている一時テーブルを作成し、そこにすべてのレコードをコピーし、メインテーブルをドロップし、正しい構造で再作成し、一時テーブルからデータを戻し、テンポラリ・テーブルを削除してアプリケーションを再起動してください。 –

関連する問題