複数のユーザーがデータベース (MySQL、Postgres) にまったく同時にデータを挿入するとどうなりますか? どのレコードを最初に挿入し、どのレコードを後で挿入するかをどのように優先しますか。回答がプログラムの適用に固有のものである場合は、Web アプリケーションを参照して質問しています。
2 に答える
一般に、2 つのことがまったく同時に起こることはありません。仕事の待ち行列があり、あるレベルでは常に 1 つのことが他の前に発生します。
ただし、トランザクション全体で複数の手順が必要になる場合があります。これらの種類のトランザクションのうち 2 つがほぼ同時に開始されると、時間的に重複する可能性があります。これにより、問題が発生する可能性があります。
たとえば、ある人がショッピング カートで何かを購入したとします。手順には、注文レコードの作成と、在庫数の減分と在庫数の減少の両方が含まれます。2 人がほぼ同時にこのプロセスを開始した場合、在庫が減少して在庫切れが表示される前に、2 人とも商品を購入する可能性があります。
このような事態が発生する可能性がある場合、postgre (およびその他の最新のデータベース) は、プログラムが自分自身を保護するように制限する方法を提供します。これらには、トランザクションとロックの両方が含まれます。
トランザクション (こちらの postgres ドキュメントを参照)では、ステートメントのグループが 1 つのユニットとして実行されます。後のステップのいずれかが失敗すると、すべてのステップが「ロールバック」されます。(たとえば、商品が在庫切れで在庫を減らすことができない場合、注文の作成をロールバックできます。)
ロック (こちらの postgres ドキュメントを参照)を使用すると、テーブル (またはテーブル内の個々の行でさえも) がロックされるため、それらにアクセスする他のプロセスは待機するか、タイムアウトになります。これにより、2 つのプロセスがほぼ同時に同じデータを更新するのを防ぐことができます。
一般に、大部分のアプリケーションでは、これらのアプローチのいずれも必要ありません。関連するテーブルに金融取引が含まれる銀行などの環境で作業していない限り、おそらく心配する必要はありません。
決して同じ時間ではありません。一方が他方より先に発生します。独自の優先順位付けメカニズムを実装しない限り、どちらになるかは不確定であり、決してそれに依存するべきではありません。
何が起こるかについては、まあそれ次第です。
同じテーブルへの 2 つの挿入の場合、データの整合性がデータベースで実行される順序に依存している場合、データベース設計には恐ろしい欠陥があります。
競合の場合 (たとえば、同じレコードに対する 2 つの更新)。2 つの実装があります。
悲観的ロック。同じデータに対してかなりの数の更新があると想定して、その周りにロックを発行します。ロックが存在する場合は、適切なメッセージで更新を失敗させます (たとえば、最初の更新が完了していない場合は 2 回目の更新)。
楽観的ロック。衝突はめったに起こらないと仮定します。これを行う通常の方法は、更新ごとに変更されるタイムスタンプ フィールドをレコードに追加することです。したがって、データを読み取るときはタイムスタンプを取得し、データを書き込むときは、タイムスタンプが現在のものと一致する場合にのみ実行し、そのタイムスタンプをその一部として更新します。一致しない場合は、「他のユーザーがこのデータ メッセージを変更しました」を実行します。
2 つの更新をマージしようとする妥協点があります。(たとえば、あなたが名前を変更し、私が住所を変更します)。ただし、それについては本当に考える必要があります。これは面倒で、すぐに非常に複雑になります。間違った実行を行うと、データが台無しになるという本当のリスクがあります。
私よりもはるかに IQ の高い人は、この作業に多くの時間を費やします。