开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜