乐观锁定是否可以阻止JPA中的阻塞?

时间:2013-02-11 23:04:52

标签: jpa optimistic-locking

我对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似乎只在绝对必要时进入数据库事务,有人可以解释乐观锁定的好处是什么?

1 个答案:

答案 0 :(得分:1)

在您的第一个示例中,您是正确的,JPA会暂停更新,直到它们必须flush为止。在第二个示例中,它必须刷新它们,以便select选择正在处理最新数据。

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

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

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