hibernate:乐观并发控制

时间:2012-11-29 03:01:27

标签: hibernate optimistic-locking

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

以下计划

  1. 打开一个会话,在表中创建一行:id = 1 name =“raj”,提交并关闭会话
  2. 开始一个线程,最初睡眠3秒。然后打开session2,更新id = 1且名称=“raj10”的人。然后session2关闭。
  3. 在session3中,我修改了相同的db行(id = 1)。但问题是,在第2步中的线程加载相同的db行之前加载此行。在session3中,已加载的db行已更新(现在这已经过时了,因为step2中的线程已对其进行了修改)。所以我抓住了staleObjectStateException。在catch块内部我再次加载它,更新然后保存它。
  4. 我收到以下异常: 线程“main”中的异常org.hibernate.StaleObjectStateException:Row被另一个事务更新或删除(或unsaved-value映射不正确):[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();
      }
      

0 个答案:

没有答案