0

我对 JPA 中乐观锁定的好处有点困惑。

我在版本化实体表上使用两个线程和一行进行了测试。
这是我发现的:

T1: begin tran
T1: fetch single entity
T1: Update field in entity
T1: sleep
T2: begin tran
T2: fetch single entity
T2: Update field in entity
T2: commit trans
T1: wake up
T1: commit trans - throws OptimisticLockException (expected)

第二次测试。注意添加了一个 select 语句。

T1: begin tran
T1: fetch single entity
T1: Update field in entity
T1: run select query on table (this causes a DB transaction to begin)
T1: sleep
T2: begin tran
T2: fetch single entity (this blocks until DB transaction of thread T1 completes!)
T2: Update field in entity
T2: commit trans
T1: wake up
T1: commit trans - ok, no exception. The fetch/update/commit of T2 happened after T1 commit. 

在使用乐观锁定时,我并没有真正期望会发生任何阻塞,但是我的理解是,必须在此处建立一个数据库事务,以便从 select 语句中返回正确的数据。
由于 JPA 似乎只在绝对必要时才进入数据库事务,任何人都可以解释乐观锁定的好处是什么?

4

1 回答 1

1

在您的第一个示例中,您是正确的,JPA 一直坚持更新,直到它绝对需要更新为止flush。在第二个示例中,它必须刷新它们,以便选择处理最新数据。

乐观锁定的一个优点是数据库不必锁定任何表。这使您的数据库可以更好地扩展,因为更多的客户端可以针对它发出语句。缺点是它将大部分并发控制转移到应用程序层。

这意味着您将需要实现错误处理或重试逻辑。如果您期望没有有争议的更新,这可能会很好。如果您希望许多客户端同时更新相同的 JPA 实体,则可能需要相当多的应用程序逻辑来处理错误并智能地重试更新,而无需诉诸“最后写入获胜”的情况。

您可能会发现这篇博文很有趣https://blogs.oracle.com/carolmcdonald/entry/jpa_2_0_concurrency_and

于 2013-02-11T23:53:38.007 回答