我目前正在使用JPA(Hibernate)的多租户applcation。对于某些表格,我需要一个对每个租户都唯一的序号。因此,我不能在这些字段中使用@GeneratedValue
。我决定使用一个名为Sequence的额外实体,其中long
字段的注释为@Version
。当请求一个新的ID我做到以下几点:JPA(多租户)中的唯一ID
Sequence seq = em.find(Sequence.class, pk, LockModeType.PESSIMISTIC_FORCE_INCREMENT);
long nextId = seq.id;
这个工作,只要我不运行应用程序的两倍。然后我得到以下异常:线程“main” javax.persistence.OptimisticLockException
异常: org.hibernate.StaleObjectStateException:行被更新或者通过 另一个事务删除(或者未保存值的映射是不正确的)
序列没有被锁定“正常”,并且一旦我提交就会得到异常。由于JPA不支持嵌套事务,因此我无法提前检测到它。我尝试了其他一些东西,但他们也失败了。
那么,有没有其他(便携式)解决方案可以让我在多租户环境中生成唯一的密钥?
我已经试过你的建议。这个解决方案的问题在于,我没有检测到事务重叠,直到我提交了整个事务(这就是我的意思是嵌套事务)。 – Dominik
那么,你不会喜欢我的建议,但是如果你真的想要嵌套事务,你可能想要抛弃Hibernate/JPA。您可以直接访问JDBC,或者使用Spring SavePoints(使用JDBC)来模拟嵌套事务:http://static.springsource.org/spring/docs/2.5.5/api/org/springframework/transaction/SavepointManager.html –