0 Replies Latest reply on Jun 21, 2007 4:39 PM by Jean-Paul Ebejer

    Locking behaviour in Hibernate - Must be missing something.

    Jean-Paul Ebejer Newbie

      Hi there at JBoss Forums,

      I am possibly missing something very obvious, but after reading loads of material I still cannot figure it out - so I'd thought I'd ask the experts.

      I have the following method in a stateless session bean (the entity manager is injected)

       public void test(String id, String value, long sleep) {
      
       SimpleTestEntityBean bean = em.find(SimpleTestEntityBean.class, id);
      
       try {
       Thread.sleep(sleep);
       } catch (InterruptedException exception) {
       exception.printStackTrace();
       }
       System.out.println(id + " setting state to " + value);
       bean.setValue(value);
      
       }
      


      Now this works fine on its own and the SimpleTestEntity 'value' field is updated accordingly.

      My problem is when I start two concurrent threads which call this method simultaneously.

      Something like


       Thread firstRunner = new Thread() {
       public void run() {
       SimpleTestFacadeAccess.getInstance().test("1", "BOGUS", 5000);
       }
       };
       Thread secondRunner = new Thread() {
       public void run() {
       SimpleTestFacadeAccess.getInstance().test("1", "OTHER_BOGUS", 2000);
       }
       };
      
       System.out.println ("Starting A simple");
       firstRunner.start();
      
       try {
       Thread.sleep(750);
       } catch (InterruptedException exception) {
       exception.printStackTrace();
       }
      
       System.out.println ("Starting B simple");
       secondRunner.start();
      


      The behaviour which I would like (which was default in 4.0.1, EJB2.1 not so many moons ago) is that the first thread which enters the session bean method takes control and locks on the entities it is going to use. So when a second thread enters the method (and the first thread is still sleeping say) the second thread has to wait for the first to finish.

      With the default behaviour - I get the lost update problem.

      x = 10
      Thread a reads x (10)
      Thread b reads x (10) (a has not read/write locked x)
      Thread a writes x=x+1 (11)
      Thread b writes x=x+2 (12) (b has old x)
      Thread a commits; (x = 11)
      Thread b commits; (x = 12)

      ... BUT x (should be) 13!

      Many Thanks
      Jean-Paul, Malta.