2014-09-19 92 views
2

我使用Spring Data Data JPA save(Object entity) method从多线程Web应用程序保存对象。休眠过时对象

偶尔我发现,当我加载的对象从使用会话:

findOne(long id)

从会话返回的对象是陈旧的,并不能反映来自数据库的最新版本。我只是从这个应用程序保存数据,并且只使用Spring Data JPA 接口的一个实例。

什么可能导致它,我应该如何解决这个问题?

+0

我检查了缓存,它使用@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) – 2014-09-23 13:20:11

回答

1

Hibernate使用PreparedStatement#executeUpdate结果来检查更新的行数。如果没有行匹配,则会抛出StaleObjectStateException(使用Hibernate API时)或OptimisticLockException(使用JPA时)。

Optimistic locking是一个通用目的的并发控制技术,它的工作原理为物理和application-level transactions

因此,当多个并发请求修改相同的共享持久数据时,陈旧的异常可以防止“丢失更新”现象。

在应用程序级事务中,一旦加载实体,由于第一级缓存(持久性上下文),您将获得逻辑可重复读取,但其他用户仍然可以修改上述实体。

因此,您确实可以遇到过时的实体,但乐观锁定机制可以防止丢失更新而不需要任何额外的数据库锁定,甚至可以用于长时间的会话。

+0

其他用户如何?我只有一个应用程序。 – 2014-09-30 13:06:17

+0

即使是单个应用程序也可能被多个并发请求访问。 – 2014-09-30 13:12:42

+0

是的,但是所有的请求都是由单例EntityManager处理的。 EntityManager不应该有任何陈旧的数据。 – 2014-10-06 14:18:24