hibernate and locking
I'm trying to exclude two reading threads from read the same record via hibernate. My SSCCE is as above, but both threads can read the object, while i was expecting that Thread-2 will throw an Exception.
The Store class is my one to create Sessions easily.
I'm testing now with HSQLDB, maybe there is no locking available ?
Update Did what Augusto propose, but still the same. Thread-2 should throw an Exception (?)
new Thread(new Runnable() { // Thread-1
@Override
public void run() {
Session ses = Store.$.ses(开发者_StackOverflow社区);
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
LockMode.Read is a shared lock, so all the reads with that lock mode will be able to read from the same source without blocking.
I think that what you want is an exclusive lock, which uses the LockMode.PESSIMISTIC_WRITE. And HSQLDB supports this type of lock (docs)
I would also add Thread.yield()
between the two threads, to allow the first one to actually start, otherwise the 2nd thread might start before the 1st one you defined.
I don't think HSQLDB has a lock timeout, and thus throw an exception when a thread is waiting for a lock for more a given amount of time. What you'll see is that the ses.load
in T2 will always happen after the ses.close
from t1.
If you have a mysql database at hand, you can update the configuration with innodb_lock_wait_timeout = 2
which will cause the DB to throw a lock timeout after 2 seconds.
精彩评论