4

問題

次のエンティティがあるとします。

@Entity
public class TimeSlot {

    @Id
    private DateTime start;
    private DateTime end;

    // other properties and accessors
}

これらのオブジェクトのいくつかを SQL データベースに格納しており、それらが重複しないことを保証できますが、これらの範囲の間にギャップが生じる可能性があります。ここで、開始日と終了日を指定するとTimeSlot、指定された間隔のすべてのギャップに新しいものを作成して永続化する関数を実装したいと思います。

public List<TimeSlot> aquireGaps(DateTime start, DateTime end);

より具体的にするために、日付の代わりに単純に整数を使用するとします。私のテーブルは次のようになります。

+-------+-----+
| start | end |
+-------+-----+
|     1 |   5 |
|     8 |  12 |
|    20 |  24 |
+-------+-----+

関数を呼び出した後aquireGaps(3, 22)、テーブルを次のようにします。

+-------+-----+
| start | end |
+-------+-----+
|     1 |   5 |
|     6 |   7 | <-- new interval fills gap
|     8 |  12 |
|    13 |  19 | <-- new interval fills gap
|    20 |  24 |
+-------+-----+

質問

問題は、これをトランザクションとして実装する方法です。具体的には、他のスレッド/プロセスが、TimeSlot操作している間隔のギャップに新しいスレッドを作成しないようにしたいと考えています。同時ユーザー数が非常に少ないため、パフォーマンスは問題になりません。実装が最も簡単なソリューションを探しています。

普通の JDBC では transaction-isolation-level を使用しますSERIALIZABLEが、JPA で分離レベルを設定する標準的な方法はありません。ベンダー固有の機能に依存しないソリューションを探しています。

あるいは、楽観的ロックを使用して、コミットが失敗した場合に再試行することもできますが、それには追加のエラー処理ロジックが必要です。

実行可能な代替手段はありますか、それとも失敗時の楽観的ロック/再試行が JPA への道ですか?

4

1 に答える 1

0

あなたが何をしようとしているのかはっきりしません。おそらくもっとよく説明してください。防止しようとしている特定の SQL の発生は何ですか?

同時挿入を回避しようとしているようです。これは、ロックまたはシリアライズ可能なトランザクション分離では役に立たないものです。行ロックは、同じ行への同時更新/削除のみを防ぎます。

2 つのトランザクションが同じ startDate を持つ TimeSlots を挿入するのを防ぐには、主キーまたは一意の制約で十分です。

http://en.wikibooks.org/wiki/Java_Persistence/Lockingを参照してください 。

于 2012-10-02T13:58:10.923 に答える