我正在尝试学习乐观并发控制。
以下程序
- 打开一个会话,在表中创建一行:id=1 name = "raj",提交并关闭会话
- 启动一个线程,最初休眠 3 秒。然后打开 session2,用 name = "raj10" 更新 id = 1 的人。然后 session2 关闭。
- 在 session3 中,我修改了相同的数据库行(id=1)。但问题是,这一行是在步骤 2 中的线程加载相同的数据库行之前加载的。并且在 session3 中,加载的 db 行被更新(现在这是陈旧的,因为 step2 中的线程已经修改了它)。所以我抓住了staleObjectStateException。在 catch 块中,我再次加载它,更新然后保存它。
我得到以下异常:线程“main”中的异常 org.hibernate.StaleObjectStateException:行已被另一个事务更新或删除(或未保存的值映射不正确):[com.raj.hibernate.optimistic.OptPerson#1]
请告诉我
- 我应该在我的 catch 块中成功更新新值。
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(); }