java - 集群环境中的 Hibernate session 缓存行为?

标签 java hibernate hibernate-session

在我参加的一次采访中,我被问到了以下问题 -

Let's say we have multi-clustered application servers, where each has created its own SessionFactory (pointing to same single DB). One server retrieves a record [Person with ID = 1] which caches the same in the session (s1), which is still open.

In the meantime, another server, opens another session (s2) and updates the Person record with ID = 1. Now what happens to the Person record cached within s1? Will it be a stale record?

我创建了一个小程序来模拟单个 JVM 上的场景。令我惊讶的是,尽管从同一个 SessionFactory 创建了 2 个 session , session 缓存仍保留了过时的数据。甚至 s1.flush() 也没有帮助。

    Session s1 = HibernateManager.getInstance().openNewSession();
    System.out.println("Opened session s1");
    Person p1 = s1.get(Person.class, 1);
    System.out.println("Retreived person with ID = 1 using s1, Name is");
    System.out.println(p1.getName()); //prints Test1
    
    Session s2 = HibernateManager.getInstance().openNewSession();
    System.out.println("Opened session s2");
    Person p2 = s2.get(Person.class, 1);
    System.out.println("Retreived person with ID = 1 using s2, Name is");
    System.out.println(p2.getName()); //prints Test1
    p2.setName("Test2");
    Transaction tx = s2.beginTransaction();
    s2.saveOrUpdate(p2);
    tx.commit();
    HibernateManager.getInstance().close(s2);
    System.out.println("Changed name and updated - closed s2");     
    
    p1 = s1.get(Person.class, 1);
    System.out.println("Retreived person with ID = 1 using s1 AGAIN, Name is");
    System.out.println(p1.getName()); //prints Test1
    
    System.out.println("Flushed s1");
    s1.flush();
    
    p1 = s1.get(Person.class, 1);
    System.out.println("Retreived person with ID = 1 using s1 AGAIN, Name is");
    System.out.println(p1.getName()); //still prints Test1. I was expecting Test2 because I flushed s1 (synced the session with DB)
    
    HibernateManager.getInstance().close(s1);

我的问题是,如果使用另一个 session 更新相同的记录, session 会使缓存失效吗?

最佳答案

是的,p1 将是一个过时的记录。如果您更新 p1,则在 session s1 的 session 刷新或事务提交时,p1 将覆盖 p2 的更新。

为了防止这种情况,您可以使用乐观锁定g。指定版本号(java源代码中的@Version)(如果有这样的列,则指定最后更新日期)并指示hibernate使用此列进行版本更新。在这种情况下,如果我们更新 p1,在 session 刷新时,hibernate 将在更新之前执行选择,查看版本信息不匹配(有人进入并更新记录)并抛出 StaleObject 异常

关于java - 集群环境中的 Hibernate session 缓存行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51270561/

相关文章:

java - 从 hibernate 迁移到另一个 ORM 工具

java - JPA cascade = REMOVE 和 Hibernate @OnDelete 一起使用?

java - 获取 IllegalStateException : Session/EntityManager is closed on session. 逐出()

java - DAO 类实例与 DAO EJB

java - 如何更改 apache poi 生成的图表以不使用平滑线并将空单元格显示为间隙?

java - 无法在不同的 spring boot 应用程序中的不同端口上启动 2 个嵌入式 active-mq

java - 有限状态机 (FSM) 和 Android 的 Java

java - 如何在运行时知道 POJO 的 ID (@GeneratedValue)

grails - Grails中的Spring Webflow保持大量休眠 session 打开

hibernate - 如何正确关闭和打开 Hibernate session ?