当前位置: 首页 > 知识库问答 >
问题:

当两个独立的应用程序使用同一个数据库时,Hibernate一级缓存结果是否会过时?

长孙作人
2023-03-14

我是hibernate的新手,我正在学习hibernate中的一级缓存。我担心一级缓存的一致性。

想象一下,我有两个独立的Web应用程序,它们可以读取/写入同一个数据库。两个应用程序都使用Hibernate。第一个应用程序由以下代码段组成。

//First Application code 
//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();

//fetch the client entity from database first time
Client client= (Client) session.load(Client.class, new Integer(77869));
System.out.println(client.getName());

//execute some code which runs for several minutes

//fetch the client entity again
client= (Client) session.load(Client.class, new Integer(77869));
System.out.println(client.getName());
session.getTransaction().commit();

第二个应用程序由以下代码组成。

//Second Application code 
//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();

//fetch the client entity from database first time
String hql = "UPDATE client set name = :name WHERE id = :client_id";
Query query = session.createQuery(hql);
query.setParameter("name", "Kumar");
query.setParameter("client_id", "77869");
int result = query.executeUpdate();
System.out.println("Rows affected: " + result);
session.getTransaction().commit();

假设第一个应用程序在上午10:00创建会话。第一个应用程序使该会话对象保持活动10分钟。同时,上午10点01分,第二个应用程序对数据库进行更新(更新客户端集名称='Kumar',其中id=77869)。

所以第一个应用程序中的一级缓存在10.01 AM之后就过时了。我说得对吗?如果是这样,有什么方法可以避免这种情况吗?


共有1个答案

弓俊晖
2023-03-14

第一个应用程序无法隐式了解第二个应用程序触发的底层更改。

处理这种情况的可能方法之一如下:

1) 一旦其中一个应用程序进行了更新/插入,就需要在数据库中保存某种标志,例如数据已更改。

2)在另一个应用程序中,您刚刚开始一个新会话,您需要检查该标志是否已设置,因此数据是否已更改。

如果是,则需要相应地设置会话的缓存模式:

session.setCacheMode(CacheMode.REFRESH);

这将确保在此会话期间,所有查询的实体不会从缓存中获取,而是从DB中获取(因此会在过程中更新缓存)。很可能这不会更新第二级更改中的所有更改,您需要不时定期设置该会话属性。

请记住,二级缓存除了字典实体之外的任何不会真正改变的东西在一致性方面都很棘手。

 类似资料:
  • 问题内容: 我需要使用Visual Studio在WinForms中开发一个简单的会计应用程序,例如客户,供应商和会计资料(借方/贷方)等。 我从未开发过使用数据库的独立应用程序,我总是开发过服务器端应用程序(现有的SQL Server等)… 我喜欢用DB开发一个独立的应用程序。我的意思是:创建一个安装项目(setup.exe / setup.msi)并发送给客户,他/她应在Windows pc上

  • 问题内容: 语境 我正在创建一个数据库环境,在该环境中,我想以几种不同的模式拆分数据以用于不同的用户组。但是,由于其中一个数据库包含公共实体,因此应该共享给所有人。 假设数据库: DB1-通用实体; 车轮实体 DB2-组“ A”; 汽车实体 DB3-组“ B”; 摩托车实体 我有三个不同的项目: 项目1: 车轮豆 专案2: 汽车制造商 专案3: 摩托车构造者 问题 我正在尝试从项目/方案(2,“

  • 问题内容: 我们有一个使用Hibernate二级缓存以避免数据库命中的应用程序。 我想知道当外部进程(例如MySQL管理员)直接连接到修改数据库(更新/插入/删除)时,是否有一些简单的方法可以使Java应用程序的Hibernate 2级缓存无效。 我们正在使用EHCache作为我们的第二级缓存实现。 我们将@Cache(usage = CacheConcurrencyStrategy.READ_W

  • 问题内容: 我知道一个事实,它是 Hibernate 使用的一级缓存,一旦我们从中检索到一个实体,便会从而不是从DB中获取具有 相同标识符 的 同一实体 的后续get调用,直到is Open 为止。 话虽如此,我对hibernate如何将第一级缓存与数据库同步感到怀疑吗?考虑以下情形 所以我的问题是 由于从一级缓存中获取,是否具有更新的值? 如果有人在会话打开时直接更新DB并修改User对象,是否

  • 我知道,会话是Hibernate使用的一级缓存,一旦我们从会话中检索到一个实体,对具有相同标识符的同一实体的后续get调用将从会话(而不是数据库)中提取,直到会话(打开)为止。 话虽如此,我对hibernate如何将一级缓存与DB同步表示怀疑?考虑以下场景 所以我的问题是 由于是从1级缓存中获取的,是否有更新的值? 如果有人在会话打开时直接更新DB并修改User对象,是否与DB同步? 提前感谢您的

  • 我有两个spring boot应用程序。 模块1在端口8080上运行 模块2在端口9090上运行 我已在应用程序中使用此属性设置端口。属性文件 这两个模块都有/登录/注册,无需通过下面的代码进行身份验证即可访问。 任何其他请求都需要对用户进行身份验证。 如果我一次使用一个模块没有问题, 但是如果尝试同时来回使用它们,那么问题是我每次使用另一个应用程序时都必须再次登录到之前的应用程序。例如。 转到模