何千人ものユーザーがデータベースの値を更新しているということですか?
4 に答える
はい、nextval
同時に動作する複数のトランザクションから安全に使用できます。それがその目的であり、存在する理由です。
とはいえ、PostgreSQL はマルチスレッド モデルではなくマルチプロセッシング モデルを使用し、ほとんどのクライアント ドライバー (libpq など) は一度に複数のスレッドを許可しないため、実際には「スレッド セーフ」ではありません。単一の接続と対話します。
また、nextval
は個別の増加する値を返すことが保証されていますが、「穴」や「ギャップ」がないことは保証されていないことにも注意してください。このようなギャップは、生成された値がコミットされずに破棄された場合 (たとえば、 によってROLLBACK
)、およびサーバーのクラッシュ後に PostgreSQL が回復した場合に作成されます。
は常に増加する数値をnextval
返しますが、これは、特定のシーケンスから ID を取得した順序でトランザクションがコミットされるという意味ではありません。したがって、次のようなことが起こるのは完全に正常です。
Start IDs in table: [1 2 3 4]
1st tx gets ID 5 from nextval()
2nd tx gets ID 6 from nextval()
2nd tx commits: [1 2 3 4 6]
1st tx commits: [1 2 3 4 5 6]
つまり、穴は現れたり消えたりします。
これらの両方の異常は、あるnextval
呼び出しが別の呼び出しをブロックしないようにするために必要であり、避けられない結果です。
このような順序付けやギャップ異常のないシーケンスが必要な場合は、一度に 1 つのトランザクションのみがコミットされていない生成 ID を持つことを許可するギャップレス シーケンス設計を使用する必要があります。これにより、そのテーブルへの挿入のすべての同時実行性が効果的に排除されます。これは通常、カウンター テーブルを使用して、SELECT FOR UPDATE
またはUPDATE ... RETURNING
カウンター テーブルで実装されます。
詳細については、「PostgreSQL ギャップレス シーケンス」を検索してください。
はい、スレッドセーフです。
マニュアルから:
nextval
シーケンス オブジェクトを次の値に進め、その値を返します。これはアトミックに行われます:複数のセッションが同時に nextval を実行したとしても、それぞれが別個のシーケンス値を安全に受け取ります。
(私のものを強調)
はい: http://www.postgresql.org/docs/current/static/functions-sequence.html
そうでなければ役に立ちません。
編集: nextval と currval の使用方法は次のとおりです。
nextval は新しいシーケンス番号を返します。これを最初のテーブルへの挿入の ID に使用します
currval は、このセッションで取得した最後のシーケンス番号を返します。それを外部キーで使用して、最初のテーブルを参照します
nextval を呼び出すたびに別の値が返されます。同じ挿入セットで 2 回呼び出さないでください。
もちろん、マルチユーザー コードではトランザクションを使用する必要があります。
この投稿者は、同じ欠陥のあるコードについて別の質問をしました。 ここで要点:彼は外部キーがどのように機能するかを知らないようで、それらを逆にしています(外部キーとして機能するシーケンスはちょっと厄介です)
ところで:これは答えではなくコメントでなければなりません。しかし、まだコメントできません。