0

我目前面临在 JPA 中锁定实体的问题。我有一个来自数据库的几个实体的列表。对于每个元素,都有一个编辑按钮,用于加载用于编辑该条目的视图。每次客户端尝试编辑条目时,我都想检查实体是否被锁定,以防止客户端甚至加载实体的编辑掩码。

我加载实体的方法:

[...]
mail = (EMailKonto) query.getSingleResult();
System.out.println(getLock(mail).toString());
setLock(mail, LockModeType.PESSIMISTIC_WRITE);
System.out.println(getLock(mail).toString());

调用的方法:

public void setLock(T entity, LockModeType lock) 
{
getEntityManager().lock(entity, lock);
}

public LockModeType getLock(T entity)
{
    return getEntityManager().getLockMode(entity);
}

发生的情况是第一个 syso 打印 NONE,因为没有应用锁。然后锁被设置,第二个 syso 打印 PESSIMISTIC_WRITE。当我刷新页面或使用另一个选项卡/浏览器并单击同一实体的编辑按钮时,第一个 syso 应该打印 PESSIMISTIC_WRITE,因为我从未删除锁定,但它再次打印 NONE。你们能帮我理解如何实现这种功能吗?

问候

4

1 回答 1

3

从技术上讲,悲观锁是通过发出SELECT ... FOR UPDATE命令来实现的,该命令锁定当前事务的行,因此其他事务中SELECT ... FOR UPDATE的任何其他以及 UPDATE 都将失败。

当事务结束时,所有事务级锁都会被释放,因此这样的实现对于您需要的功能是不可行的,因为只要客户端正在编辑行,您就需要保留事务。可以在重型客户端中实现(虽然设计很糟糕),但在 Web 应用程序中是不现实的,因为如果客户端关闭浏览器,您甚至没有反馈。

您需要通过将“锁”存储在单独的表中来手动实现和管理业务级别的锁。事务级(悲观)锁的设计目的不是用作业务级锁。它们是旨在断言事务一致性的低级机制。

于 2014-10-14T06:49:30.077 回答