2011-09-19 118 views
0

我想排除两个阅读线程通过休眠读取相同的记录。我的SSCCE和上面一样,但是两个线程都可以读取对象,而我期待Thread-2会抛出异常。休眠和锁定

Store类是我轻松创建Sessions的一个类。

我现在用HSQLDB测试,也许没有锁定可用?

更新做了什么奥古斯托建议,但仍然是一样的。线程2应抛出异常(?)

 new Thread(new Runnable() { // Thread-1 

      @Override 
      public void run() { 
       Session ses = Store.$.ses(); 
       Object x = ses.load(Client.class, 1l, 
         new LockOptions(LockMode.PESSIMISTIC_WRITE)); 
       System.err.println("T1 :"+(x==null)); 
       try { 
        Thread.sleep(10000); 
       } catch (InterruptedException ex) { 
       } 
       ses.close(); 
      } 
     }).start(); 

     Thread.yield(); 

     new Thread(new Runnable() { // Thread-2 

      @Override 
      public void run() { 
       try { 
        Thread.sleep(2000); 
       } catch (InterruptedException ex) { 
       } 
       Session ses = Store.$.ses(); 
       Object x = ses.load(Client.class, 1L, 
         new LockOptions(LockMode.PESSIMISTIC_WRITE).setTimeOut(1)); 
       System.err.println("T2 :"+(x==null)); 
       ses.close(); 
      } 
     }).start(); 

Output: 

T1: false 
t2: false 
+0

请检查更新 – Augusto

回答

1

LockMode.Read是一个共享锁,因此与该锁定模式中的所有读取将能够从相同的源读取不受阻塞。

我认为你想要的是一个独占锁,它使用LockMode.PESSIMISTIC_WRITE。和HSQLDB支持这种类型的锁(docs

的我还要补充Thread.yield()两个线程之间,以使第一个真正开始,否则你定义的第一个1之前的第2个线程可能开始。


我不认为HSQLDB有锁超时,从而抛出当一个线程在等待的时间更给定数量的锁异常。你会发现T2中的ses.load将始于t1之后的ses.close

如果您手边有mysql数据库,您可以使用innodb_lock_wait_timeout = 2更新配置,这将导致DB在2秒后引发锁定​​超时。