PeterMmm
PeterMmm

Reputation: 24630

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();
                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

Upvotes: 0

Views: 1967

Answers (1)

Augusto
Augusto

Reputation: 29827

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.

Upvotes: 1

Related Questions