-1

すべてのアクティビティ (読み取りと書き込み) に対してテーブルをロックする必要があると思われるシナリオがあります。私は Propel 1.6.x を使用しており、ロックを処理するための小さな追加ライブラリを作成するつもりです。

私の使用例は、(id、作成者、バージョン) の主キーを持つバージョン テーブルです。列のペア (id、作成者) は、実際には別のテーブルの PK です。新しい行が挿入されると、MAX(バージョン) が PHP コードで読み取られ、後で保存するために行クラスに挿入されます。最大値と保存の間に、別のプロセスが同じ最大値を取得する可能性のある競合状態があり、もちろん、一意性がないために挿入の 1 つが失敗します。

ロックの必要性を避けるために、次のような保存にサブセレクトを使用することをお勧めします。

INSERT INTO
    test_model_test_organiser_versionable
(id, creator, version)
VALUES (
    3,
    1, 
    (
        SELECT COALESCE(MAX(version), 1)
        FROM test_model_test_organiser_versionable
        WHERE id = 3
        AND creator = 1
    )
);

しかし、これは Propel ではサポートされておらず、PDO を介して行う場合、複合 PK の「バージョン」部分に与えられた値を発見する方法がありません (私の知る限り)。

自動インクリメントされた値は、行を検索するために挿入後に読み取られるため、Propel で再選択を行うことができます。しかし、できれば不要な列は避けたいと思います - 私の意見ではエレガントではないようです。

だから...私の気持ちは、max&save呼び出しをロックでラップすることが道だと思います。これは、テーブル IMO 全体をロックし、読み取りと書き込みを防ぐ必要があります (そうしないと、後続の max 呼び出しが待機せず、非一意性エラーが再び発生する可能性があります)。

Propel でサポートされているすべてのプラットフォームで動作するためにこれが必要です。より良いアプローチがない限り、PDO データベースに対してこのロックを行う PHP ライブラリはありますか? そうでない場合は、自分で行うことができます-しかし、他の誰かがさまざまなデータベースに対してドンキーワークのテストを行っているといいです(MSSQLサーバーをセットアップしますか?-いいえ:)

4

1 に答える 1

1

MAX() と INSERT/UPDATE が完了している間、テーブルを完全にロックしました。これらが機能することがわかりました:

  • MySQL:LOCK TABLES my_table WRITE
  • PostgreSQL:LOCK TABLE my_table IN SHARE ROW EXCLUSIVE MODE

そのうち、Oracle、MSSQL、SQLite についても同じものを調べてテストする予定ですが、最初の 2 つはおそらく F/OSS プロジェクトで最も人気があります。

于 2011-11-08T00:07:23.820 に答える