私は、MySQLインベントリデータベースと対話するAPIを作成しています。Laravelの並行処理について
on-hand
値を小さくし、製品のreserved
価値を高める:私たちは、15次の方法でデータベースを更新し、製品を予約することができ、ユーザーを持っています。
inventory
表は次のようになります。
id int
sku varchar
on-hand int
reserved int
問題がある:2人のユーザーが、同時にそれを更新しようとした場合、行の更新を処理するためにどのように?
iはTransactionsを使用していた考えていた最初のaproach:
<?php
function reserveStock()
{
$db->beginTransaction();
// SELECT on-hand, reserved from inventory
// Update inventory values
$db->commit();
return response()->json([ 'success' => 1, 'data' => $data ])
}
第二つpessimist lockingを用いた:
<?php
function reserveStock()
{
// SELECT on-hand, reserved from inventory with ->sharedLock()
// Update inventory values
return response()->json([ 'success' => 1, 'data' => $data ])
}
第三の一つはCEROの値とupdating
フィールドを作成することでした。更新する製品を選択するときに、その行で何かをする前にupdating
フィールドをチェックします。私がここに見る問題は、利用可能になるまで、updating != 0
でループする必要があるということです。より多くの選択と更新が彼のaproachから来る。
最高の場合、どのような行動が起こりますか?私がここに書いたものよりも多くの選択肢があるかもしれません。
2人のユーザーが同時に更新されないように対処する方法はありません。第2の更新は、第1の更新後にキューに入れられて実行されます。最後に更新したユーザーのデータが常に終了します。これはlaravelではなくデータベース設計に関連しています。各ユーザーが株式に行ったことを示す履歴表が必要です。後の計算は、合計または控除など、履歴テーブルを使用して必要なものです。 15人のユーザーで、2人が排他的な更新権限で「戦う」というチャンスはほとんどゼロです。より堅牢にする必要があります。 –
私は実際に履歴表(kardex)を使ってデータベースを設計しましたが、ある時点でテーブルが何千もの行になり、値を再計算する必要があるためプロセスが遅くなると考えていました。 @ N.B。どう思いますか? – aerojun
何十億もの行があるとすれば、それは少し問題になります。何千ものことではありません。数字を出すために常に表全体を調べる必要はなく、ある時点で在庫数を常に実体化し、そこから続けることができます。在庫を処理する場合は、在庫を追跡できるように履歴テーブルを用意する必要があります**。履歴表を使用すると、必要な数をいつでも知ることができます(10個の在庫がある場合、2個が売れ、1個が破損した場合は7個を販売します。 –