• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Record lock/unlock with Iterator (???)

 
Andras Nemeth
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I just finished my lock/unlock, but I am not quite satisfied with the result.
My LockManager contains the following methods:
registerLock(int recno, Connection conn)
unregisterLock(int recno, Connection conn)
unlockClient(Connection conn)
The problem was at unlockClient, which would unlock all the record that the client locked (called form unreferenced).
I store the locks in a Map (synchronized HashMap) and
get the Iterator with lockHolder.entrySet().iterator();
Then I iterate through while hasNext() true.
In the iteration I create a Map.Entry from the lockIterator.next() and use the entry's getValue and getKey methods to check which recordlocks connect to this client.
Here is the problem when I found one lock, I try to remove it from the HashMap. Actually, I tried with lockHolder.remove() and my unregisterLock(...) also. Both failed with ConcurrentModificationException.
I found that it fails after it removed one lock and call the lockIterator.next() (or hasNext()) so it is invalid by this time (because I modified the lockHolder Map)...
I found out then when I use the remove() method of the iterator it works fine. Is it ok or it is a dirty solution? (I do
not like it...) I also have to call the notifyAll() after removing the elements form lockHolder. (The unregisterLock
would do the same, but it fails...)
Any advise how can I make it better?
Thanks.
Bye,
Ban
 
Andras Nemeth
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Also here the exception:
unlcokClient: The client suncertify.db.ConnectionImpl[RemoteStub [ref: [endpoint
:[145.247.17.223:4922](local),objID:[2]]]]unlocked recno: 2
registerLock: Recno:1 already locked by suncertify.db.ConnectionImpl[RemoteStub
[ref: [endpoint:[145.247.17.223:4922](local),objID:[2]]]] so wait()java.util.Con
currentModificationException
at java.util.HashMap$HashIterator.next(HashMap.java:736)
at suncertify.db.LockManager.unlockClient(LockManager.java:58)
at suncertify.db.ConnectionImpl.unreferenced(ConnectionImpl.java:87)
at sun.rmi.transport.Target$1.run(Target.java:323)
at java.lang.Thread.run(Thread.java:484)
Ban
 
Jon Trussler
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ban,
I basically do the same thing.
1) check to see if there are any locks held by this connection; if so continue.
2) get a key set from my locking structure
3) get the iterator from this set
4) loop through the keys and if the value associated with the key is the dead connection, call the iterator's remove method and notify all
i haven't found anything more efficient than this but since the code is not completely executed unless step 1) is true, i don't think it will be a performance hit. basically, step 1 should never evaluate to true unless the client quits abnormally or the client is not well-behaved.
What do you think?
Jon
 
Andras Nemeth
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Jon,
I am happy that you walks the same road.
Now, I am thinking about db lock.
I will put -1 into the lock holder and check every time when sb wants to lock a record whether there is -1 in the lock holder object. (So, there is no record lock until db lock exists.)
What should I do with the incoming record lock requests during there is db lock. I guess I will throw an exception... I do not like the wait() (and notify()) idea here for db lock.
But, how about the db lock... Does it has to wait until all the record locks are removed? It seems to me sense, but it might take a long time.
Any idea?
Thanks.
Ban
 
Peter den Haan
author
Ranch Hand
Posts: 3252
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A few general remarks...
1. Beware of synchronized collections. They may lure you in a false sense of security and muddle your algorithms. I would encourage you to start out without synchronized collection, think it through using explicit synchronization, and replace it by a synchronized collection afterwards if you think it makes things simpler.
2. Even if your collection is synchronized, its iterators are not. They are thread-unsafe and need to be used within a synchronized(myCollection) { } block. See point 1.
3. But quite apart from threading issues, any modification to a collection will break open iterators. The only exception is a modification made through the iterator itself - and even then it will break all other iterators.
- Peter

[This message has been edited by Peter den Haan (edited August 29, 2001).]
 
Andras Nemeth
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Peter,
Thank you for your valuable answer.
I do not trust in synchronized collections, so I use synhronized blocks in my locking mechanism. Anyhow, it is a good idea to trye out with an unsynchronized collection!
To 3.: I did not know about connection between collection and iterators. Now I understand why I got a ConcurrentModificationEception. Thanks for turn some lights on it.
What do you think about my db lock questions?
Have fun,
Ban
 
Andras Nemeth
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
I am going to walk the road which won't allow more record locks during db lock and wait for db lock while there is record lock in the table...
Is it seems to be sense or did I miss something?
Ban
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic