我有一个关键的代码部分,我需要使用悲观锁通过 id 读取和锁定实体。这部分代码现在看起来像这样:MyEntity entity = entityManager.find(MyEntity.class, key);entityManager.refresh(entity, LockModeType.PESSIMISTIC_WRITE);它工作正常,但据我了解,如果休眠缓存中没有实体,我们将使用 2 个读取事务到数据库。第一个事务通过 id 查找实体,另一个事务刷新和锁定实体。在这种情况下是否可以只使用一个事务?我会想象这样的事情:boolean skipCache = true;MyEntity entity = entityManager.find(MyEntity.class, key, LockModeType.PESSIMISTIC_WRITE, skipCache);但是没有像skipCache. 是否有另一种方法可以使用 id 直接从数据库中读取实体EntityManager?更新:如果实体存在于缓存中,此查询将命中一级缓存。因此,它可能会返回过时的数据,这就是为什么它不适合应该阻止任何读取的关键部分:MyEntity entity = entityManager.find(MyEntity.class, key, LockModeType.PESSIMISTIC_WRITE);问题是关于跳过缓存而不是锁定。
2 回答
慕尼黑的夜晚无繁华
TA贡献1864条经验 获得超6个赞
我刚刚getReference
在EntityManager
其中找到了一个获取实例的方法,该实例的状态可能会被延迟获取。如文档中所述:
获取一个实例,其状态可能会被延迟获取。如果请求的实例在数据库中不存在,则在第一次访问实例状态时抛出 EntityNotFoundException。(当调用 getReference 时,允许持久性提供程序运行时抛出 EntityNotFoundException。)应用程序不应期望实例状态在分离时可用,除非它在实体管理器打开时由应用程序访问。
作为在一个查询中通过 id 查找和锁定最新实体的一种可能解决方案,我们可以使用以下代码:
MyEntity entity = entityManager.getReference(MyEntity.class, key); entityManager.refresh(entity, LockModeType.PESSIMISTIC_WRITE);
此查询将创建一个实体(无数据库查询),然后刷新并锁定该实体。
添加回答
举报
0/150
提交
取消