gpt4 book ai didi

java - 加载实体而不锁定数据库中的行

转载 作者:行者123 更新时间:2023-12-01 11:02:03 25 4
gpt4 key购买 nike

JPA 中是否有一个选项可以在不锁定数据库的情况下加载实体(或实体列表)?我希望能够通过几种方法来做到这一点。JPA 是否可以在不锁定数据库的情况下加载实体,但是当该实体发生任何更改时,它就会锁定数据库中的行?当然,如果数据库中的实体已更改,则验证状态会引发无效状态异常。

最佳答案

Is there an option in JPA to load an entity (or a list of) without locking the database?

实体可以通过不同的EntityManager调用来加载:

  • EntityManager.find
  • EntityManager.createQuery
  • EntityManager.createNamedQuery
  • EntityManager.createNativeQuery

您无需在这些调用中显式使用 LockModeType.None。这是 JPA 中的默认选项,由 LockModeType.None 表示。

Also is it possible for JPA to load the entity without locking the database, BUT when anything change on that entity, just then it lock the row in the database?

可以通过不同的调用来锁定实体:

  • EntityManager.find
  • EntityManager.lock
  • EntityManager.refresh
  • Query.setLockMode

我想说这是可能的,但 JPA 不能保证,因为它取决于持久性提供程序(特定于供应商)和所使用的锁定类型。

无论如何,这种情况可能看起来像这样:

// begin tx
...
SomeEntity e = em.find(SomeEntity.class, id);
// change the entity
em.lock(e, LockModeType.OPTIMISTIC); // LockModeType.OPTIMISTIC_FORCE_INCREMENT
...
// commit tx

现在,这取决于持久性提供者是急切锁定(当调用锁定时)还是延迟锁定(当 tx 完成时)。请记住,另一个事务可能会将实体锁定为第一个事务,并且您最终将进行回滚。

摘自JPA规范2.03.4.4.1 OPTIMISTIC、OPTIMISTIC_FORCE_INCRMENT章节:

If transaction T1 calls lock(entity, LockModeType.OPTIMISTIC) on a versioned object, the entity manager must ensure that neither of the following phenomena can occur:

  • P1 (Dirty read): Transaction T1 modifies a row. Another transaction T2 then reads that row and obtains the modified value, before T1 has committed or rolled back. Transaction T2 eventually commits successfully; it does not matter whether T1 commits or rolls back and whether it does so before or after T2 commits.
  • P2 (Non-repeatable read): Transaction T1 reads a row. Another transaction T2 then modifies or deletes that row, before T1 has committed. Both transactions eventually commit successfully.

This will generally be achieved by the entity manager acquiring a lock on the underlying database row. While with optimistic concurrency, long-term database read locks are typically not obtained immediately, a compliant implementation is permitted to obtain an immediate lock (so long as it is retained until commit completes). If the lock is deferred until commit time, it must be retained until the commit completes. Any implementation that supports repeatable reads in a way that prevents the above phenomena is permissible

If transaction T1 calls lock(entity,LockModeType.OPTIMISTIC_FORCE_INCREMENT) on a versioned object, the entity manager must avoid the phenomena P1 and P2 (as with LockModeType.OPTIMISTIC) and must also force an update (increment) to the entity's version column. A forced version update may be performed immediately, or may be deferred until a flush or commit.

关于java - 加载实体而不锁定数据库中的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33263722/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com