4

短期間に多くのユーザーがチケットを予約し、合計で一定数しか予約できないシステムを作っています。600 枚のチケットが利用可能で、すべてが 3 時間以内に予約される可能性があるとします。

理想的には、予約の上限に達しないようにしたいので、予約を作成する前に、利用可能なチケットの数に対して予約が可能かどうかを確認しています. 重要なのは、チケットの制限を超えないようにするために、そのチェックとユーザーへのチケットの割り当ての間に更新が行われないようにする必要があることです。

これを達成するためにmysqlテーブル書き込みロックを使用しようとしていますが、codeigniterフレームワーク内でこれを実装する際に問題が発生しています。これを処理するモデル内で、いくつかの関数を作成しました。1 つは予約を作成するためのもので、もう 1 つはさまざまな種類のチケットの数をカウントするためのものです。問題は、チケット カウント機能がロックされているため、同じデータベース セッションを共有していないように見えることです。

実行順序は

  • コントローラーで $this->model_name->create_reservation を実行します
  • model_name->create_reservation でロック クエリを実行します
  • model_name->create_reservation のコール カウント メソッド
  • おそらく別のデータベースセッションを使用しているため、カウント関数(model_nameクラスのメソッド)がロックアップしますか?

データベース ライブラリは、$this->load->database(); を使用してモデルの __construct メソッドにロードされます。

何か案は?

4

1 に答える 1

3

mysql では、テーブルが自動ロックされるクエリを実行する前に、DB ハンドルでこれらのコマンドを実行します。

begin work;

次に、クエリを実行するか、その db ハンドルを使用してコード イグナイターにさまざまな選択と更新を実行させます。

次に、あなたのどちらか

commit;

また

rollback;

選択した行はロックされ、他のプロセスで読み取ることはできません。行を引き続き読み取り可能にしたい場合は、次のようにします。

Select ... IN SHARE MODE

Mysql ドキュメントから:

http://dev.mysql.com/doc/refman/5.5/en/select.html

ページ ロックまたは行ロックを使用するストレージ エンジンで FOR UPDATE を使用する場合、クエリによって検査される行は、現在のトランザクションが終了するまで書き込みロックされます。LOCK IN SHARE MODE を使用すると、他のトランザクションが検査された行を読み取ることを許可する共有ロックが設定されますが、それらを更新または削除することはできません。セクション13.3.9.3「SELECT ... FOR UPDATE および SELECT ... LOCK IN SHARE MODE ロック読み取り」を参照してください。

別の人がすでにコメントでこれを言っていますが、CIドキュメントから:

$this->db->trans_start();
$this->db->query('AN SQL QUERY...');
$this->db->query('ANOTHER QUERY...');
$this->db->query('AND YET ANOTHER QUERY...');
$this->db->trans_complete(); 

trans_start と trans_complete は、ハンドルでこれらのクエリを実行します...

おそらくtrans_rollbackもあります...

于 2011-09-21T23:48:03.407 に答える