0

オンラインスケジュールアプリを開発中です。1 つのスケジュールを複数のユーザーが同時に編集できます。非常に重要なビジネス上の制約が 1 つあります。1 日に 3 つのイベントのみが発生する必要があります。

技術的に言えば単純化すると、データベースには次の列を持つテーブルがあります。ID | イベント | 日付 |。アプリケーションはトランザクション「select... count... where...」で実行され、結果が 3 未満の場合、新しいイベントが挿入されます。

2 つのスレッドが 1 日に 4 つのイベントを作成しないことを保証するには、どのアプローチを使用できますか? これは、古典的なチェック アンド ライトの問題です。そして、データベースレベルでどのように解決できるのだろうか?

トランザクションを使用しても、2 番目のトランザクションで別のスレッドが同じことをしないとは限りません。イベントの数が 3 未満であることを確認し、挿入を行います。テーブル全体をロックすることは、応答時間や同時実行性などが低下するため、受け入れられません。

アプリケーションは、Spring、Hibernate、MySQL を使用して Java で開発されています。

アドバイスをよろしくお願いします。

4

3 に答える 3

0

データ モデルでは、チェック制約を使用して行数をカウントできます。私の知る限り、MySQLはこのタイプの制約をネイティブにサポートしていませんが、トリガーでそれらをエミュレートすることは可能のようです

daysまたは、テーブルとテーブルを使用した別のデータ モデルを検討することもできeventsます。の楽観的ロックを使用daysして、2 番目のトランザクションが古いデータを理解していないことを確認できます。

于 2011-08-24T12:08:55.093 に答える
0

Spring を使用していて、同時実行の問題があるため、DB レイヤーではなく Java レイヤーで実行を同期してみてください。DB を使用して並行性を維持しようとしたときに、同様の問題が発生しました。

おそらく、Java で実行ブロックを作成して、実行synchronizedを強制的にブロックすることができます。同期されたメソッド内で、すべてのビジネス ロジックが true を返すことを確認します。true の場合、通常の実行を続行します。false の場合、例外で中止します。

于 2011-08-24T13:35:23.500 に答える
0

プロセスをブロックするには、Select ... FOR UPDATE ステートメントを使用する必要があります。ただし、これは innodb でのみ機能します。

例:

//java logic
try {
    //mysql logic
    start transaction;
    select * from where 'some condition' FOR UPDATE
    INSERT INTO TABLE ....    
    commit;
//java logic
catch (Exception e) {
    rollback;
}

特定の行ロックに関する詳細情報を参照してくださいhttp://dev.mysql.com/doc/refman/5.1/en/innodb-locking-reads.html

于 2011-08-24T12:33:42.353 に答える