2017-10-17 140 views
2

我有一个java方法在事务中运行,我使用以下JPA查询读取Oracle数据库表,然后使用以下查询的结果在同一个表中插入新记录。我想了解锁模式PESSIMISTIC_WRITE将在这种情况下工作。当执行下面的查询时,整个表是否会被锁定,阻止从该表读取其他数据,直到我的方法在插入后提交事务为止?JPA锁定模式行为

@NamedQuery(name = "findByMaxSeqForGivenOrd", query = "select ar from Remark ar 
where ar.sequenceNumber = (select max(ar1.remarkId.sequenceNumber) from Remark ar1 
where ar1.remarkId.orderNum = ar.remarkId.orderNum 
AND ar1.remarkId.orderNum=:orderNum)", 
lockMode=LockModeType.PESSIMISTIC_WRITE, 
hints = @QueryHint(name = "javax.persistence.lock.timeout", value = 
"3000")) 

回答

0

如果您在查询中使用LockModeType.PESSIMISTIC_WRITE,那么你最终会加入Serializable隔离级别Oracle数据库等效。

在数据库级别只相当于结果实体的行会与一些东西被锁定要考虑:

  • 实体关系为其锁定实体包含外键也将被锁定,但不被引用实体的状态(除非这些实体被显式锁定)。

  • ElementCollections以及实体未包含外键的关系:@OneToMany,@ManyToMany;将不会被默认锁定。如果用一个值PessimisticLockScope.EXTENDED指定了“javax.persistence.lock.scope”属性

  • ElementCollections,并与由包含在连接表的实体所拥有的关系将被锁定。

+0

谢谢。所以如果我的表有orderNum和seqNum列和三条记录(1,1),(1,2),(2,1),并且我在原始问题中使用查询来查找orderNum为1的记录(seqNum) ,它会返回(1,2),那么对于这种情况,运行orderNum 1的相同查询的另一个事务将等待,直到第一个事务提交?怎么样插入?其他事务是否能够为相同的orderNum插入新行:1? – ppatidar

+0

t2将根据超时设置等待,并且您不能在同一个pk中插入新行 –

+0

对不起。我的意思是插入不同的PK。我正在做的读取是生成新的序列号。我有一个现有的表, orderNum和SeqNum是PK的一部分。 SeqNum重置为1以获得新订单Num此表当前正在通过Pro * c代码访问,现在我必须使用JPA。在这种情况下,我找不到可以使用的PK生成策略。 – ppatidar