如何使用JPA以并发安全的方式获取非重叠日期范围的差距?

时间:2012-10-02 11:47:30

标签: java jpa jpa-2.0

问题

假设我有以下实体:

@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中,我会使用事务隔离级别SERIALIZABLE,但是没有标准的方法来在JPA中设置隔离级别。我正在寻找一种不依赖于供应商特定功能的解决方案。

或者我可以使用乐观锁定并在提交失败时重试,但这需要额外的错误处理逻辑。

是否存在任何可行的替代方案,或者在JPA的方式上是否存在乐观的锁定/重试失败?

1 个答案:

答案 0 :(得分:0)

我不清楚你要做什么,或许更好地解释。您试图阻止哪些特定SQL出现?

您似乎试图避免并发插入,这是锁定或可序列化的事务隔离无法帮助您,行锁定仅阻止对同一行的并发更新/删除。

主键或唯一约束应足以防止两个事务插入具有相同startDate的TimeSlots。

请参阅, http://en.wikibooks.org/wiki/Java_Persistence/Locking