問題
次のエンティティがあるとします。
@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 への道ですか?