【问题标题】:JPA Lock Mode behaviourJPA 锁定模式行为
【发布时间】:2018-03-29 13:26:56
【问题描述】:

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

    @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"))

【问题讨论】:

    标签: java oracle jpa openjpa


    【解决方案1】:

    如果您在查询中使用 LockModeType.PESSIMISTIC_WRITE,那么您最终会在 oracle db 上添加等同于 Serializable 的隔离级别。

    在数据库级别,只有与结果实体对应的行会被锁定,需要考虑的事项很少:

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

    • ElementCollections 和实体不包含外键的关系:@OneToMany@ManyToMany;默认不会被锁定。

    • 如果“javax.persistence.lock.scope”属性的值指定为PessimisticLockScope.EXTENDED,则连接表中包含的实体拥有的ElementCollections 和 和 关系将被锁定。

    【讨论】:

    • 谢谢。因此,如果我的表有 orderNum 和 seqNum 列以及三个记录(1、1)、(1、2)、(2、1),并且我使用原始问题中的查询来查找 orderNum 1 的 max(seqNum) 记录,这将返回 (1, 2) 那么对于这种情况,另一个对 orderNum 1 运行相同查询的事务将等到第一个事务提交?插入呢?其他事务是否能够为相同的 orderNum:1 插入新行?
    • t2 将根据超时设置等待.. 无论如何您都不能插入具有相同 pk 的新行
    • 对不起。我的意思是插入不同的PK。我正在做的读取是生成新的序列号。我有一个现有的表,其中 orderNum 和 SeqNum 是 PK 的一部分。对于新的 orderNum,SeqNum 重置为 1,此表当前正在由 Pro*c 代码访问,现在我必须使用 JPA。我找不到可以在这种情况下使用的 PK 生成策略。
    • 这似乎是不同帖子的情况。底线是其他事务将能够使用该锁定模式读取或更新查询实体
    • 您的意思是其他事务将无法读取或更新吗?还是我误解了您提到的第二条评论 t2 将根据超时等待?
    猜你喜欢
    • 2012-11-14
    • 2012-11-14
    • 1970-01-01
    • 2019-02-03
    • 2016-12-04
    • 2016-09-23
    • 2011-03-30
    • 1970-01-01
    • 2020-01-15
    相关资源
    最近更新 更多