1

我正在尝试学习乐观并发控制。

以下程序

  1. 打开一个会话,在表中创建一行:id=1 name = "raj",提交并关闭会话
  2. 启动一个线程,最初休眠 3 秒。然后打开 session2,用 name = "raj10" 更新 id = 1 的人。然后 session2 关闭。
  3. 在 session3 中,我修改了相同的数据库行(id=1)。但问题是,这一行是在步骤 2 中的线程加载相同的数据库行之前加载的。并且在 session3 中,加载的 db 行被更新(现在这是陈旧的,因为 step2 中的线程已经修改了它)。所以我抓住了staleObjectStateException。在 catch 块中,我再次加载它,更新然后保存它。

我得到以下异常:线程“main”中的异常 org.hibernate.StaleObjectStateException:行已被另一个事务更新或删除(或未保存的值映射不正确):[com.raj.hibernate.optimistic.OptPerson#1]

请告诉我

  1. 我应该在我的 catch 块中成功更新新值。
  2. session.merge 会在这里帮助我吗?

    final SessionFactory factory = new Configuration().configure()
            .buildSessionFactory();
    Session session = factory.openSession();
    session.beginTransaction();
    OptPerson optP1 = new OptPerson();
    optP1.setName("raj");
    session.save(optP1);
    session.getTransaction().commit();
    session.close();
    System.out.println("done saving, closed session");
    
    new Thread() {
        public void run() {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            Session session2 = factory.openSession();
            session2.beginTransaction();
            OptPerson p1 = (OptPerson) session2.get(OptPerson.class, 1);
            p1.setName("raj10");
            session2.save(p1);
            session2.getTransaction().commit();
            session2.close();
            System.out.println("modified person in session2");
        }
    }.start();
    
    Session session3 = factory.openSession();
    session3.beginTransaction();
    OptPerson p1 = (OptPerson) session3.get(OptPerson.class, 1);
    System.out.println("read person in session3");
    Thread.sleep(8000);
    try {
        p1.setName("man");
        session3.save(p1);
        session3.getTransaction().commit();
    } catch (StaleObjectStateException ex) {
        System.out.println("inside catch block");
        OptPerson p3 = (OptPerson) session3.get(OptPerson.class, 1);
        p3.setName("man");
        session3.saveOrUpdate(p3);
        //OptPerson p4 = (OptPerson) session3.merge(p1);
        session3.getTransaction().commit();
    } finally {
        session3.close();
    }
    
4

0 回答 0