[SCJP, SCJD]
Surely, if a connection knows what it has locked then it can ensure by itself that it does not unlock a record that it has not locked.
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
There are issues though if you do not have a Connection Factory, or if you try and have the client side of the connection checking ownership.
The other alternative is, of course, to have a single instance of LockManager (per table), which would maintain the mapping between the clients and the locked records. Both solutions seem fine to me, although the LockManager gives you a little more encapsulation and control.
[SCJP, SCJD]
What do you mean by Unferenced in your comments? Does the design explained allow for recovery of locks if the client crashes?
Where does this list of records reside?
What use if any is there in making use of a seperate class such as LockManager for this purpose?
Conceptually, i see that having a LockManager would just be a place to localise the mapping of client connections to locks. Is this necessary to recover from client crashes? Can connections themselves know how to recover locks from such an occurance?
I have a couple ideas here but would like to hear yours first.
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
A LockManager does know who owns what locks and so it could perform deadlock detection as well
[SCJP, SCJD]
You seem to agree that it is feasible for connections to maintain references to locks it owns and also discuss having a LockManager to maintain references between Connections and the LockManager. Are these different suggestions
If deadlock actually occured then what could LockManager do about it? I thought that preventing deadlock would be the responsibility of the client?
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
I found that if I used a LockManager there was quite tight coupling between the Connection instances and the LockManager class. Meaning that they passed quite alot of arguments to each other. If they exhange or share quite of lot of information then surely their responsibilites are quite tightly coupled? .. tight enough to reside in a single class?
A LockManager does know who owns what locks and so it could perform deadlock detection as well.
I thought that preventing deadlock would be the responsibility of the client?
If deadlock actually occured then what could LockManager do about it?
Andrew: By the way - this is in part just a theoretical discussion answering your question on what the benefits of having a lock manager are. I am not sure that deadlock prevention is required by the assignment.
Is there any possibility of a deadlock? Where two or more clients are waiting for each other's locks?
<Exam Watch!> Check for this more than you check for anything else.
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
General Considerations (100 points)
Documentation (70 points)
Object-orietned design (30 points)
User Interface (40 points)
Locking (80 points)
Data class (40 points)
Server (40 points)
Is there any possibility of a deadlock? Where two or more clients are waiting for each other's locks?
[SCJP, SCJD]
[SCJP, SCJD]
But why is the advice given in your reference material not a statement, but rather a question?
The way i have implemented the client there is no way for deadlock to occur.. so it this really necessary?
It is always possible to envisage hostile clients causing deadlock.
Originally posted by Patrick Cobbett:
Hi Max, i've read you discuss having a WeakHashMap in the Data class in other posts to map client connections to records..
..Firstly, do you think that the Data class is really where it should reside? Are you implying that the Data class would be dependant on the Connection class? On a higher level it would mean that the database package would depend on the network package, which would already necessarily depend on the database package. Violation if ADP?
Your discussion of a WeakHashMap has inspired me, but perhaps it should reside else where. Either in a LockManager or a static member of Connection?
By the way, incase you missed my last reply to another post i enjoyed your book.
But I think Data is really supposed to be your low level DB API.
In this scenario, you don't need a lock manager at all, because the Data object handles it's own internal problems and conflicts, like a good object is supposed to.
This is a bad idea. RMI makes no guarantees with respect to mapping remote object invocations to threads. That means that client A may use thread T1 to lock a record, and then use thread T2 to unlock the same record.
Originally posted by Andrew Monkhouse:
Hi Patrick
For example, consider the following scenario:Client A locks record 1. Client B locks record 2. Client A attempts to lock record 2. Client B attempts to lock record 1
It is only the server that could detect this scenario and act on it.
Regards, Andrew
Originally posted by Philippe Maquet:
Hi Max,
I don't agree with you, here. By letting Data delegating the whole locking mechanism to a separate class - independant from Data itself - , you get a few pros "for free" :
easiness in testing (BTW I could test LockManager before the first line of Data was ever written) reusability (locks are served and managed to any caller class, Data here but any other class if needed) code clarity (LockManager just handles locks, but it's enough complexity to manage it in its own "box")
From the outside world, it doesn't change anything : LockManager is a package-level class, so Data is the only visible db class.
Any comment of you will welcome : I am a Java newbie while you (I know it not from reputation but because I read your book) are an expert.
Cheers,
Phil.
Philippe: I read Kathy Sierra & Bert Bates's book too. Great as far as SCJP is concerned, a little "lightweight" in comparison with Max's one for SCJD.
Patrick: It is always possible to envisage hostile clients causing deadlock. But why is the advice given in your reference material not a statement, but rather a question? Why does it not say that all locking mechanism should implement a dead-lock recovery scheme?
Andrew, one furthur comment. If your Data class 'has' a LockManager, then does your lock() method take the connection as an argument?
Patrick: If i used a LockManager then it would have to be 'used' by Connection, which would mean the that Connection would be passing references to itself in method calls to lock requests by LockManager. I have no real problem with this but you requiring clarification.
Patrick: Could i suggest that the question is saying that IF there is a possibilty of deadlock as a result of the way inwhich the clients behave, then dead-lock recovery would be necessary.
Patrick: With respect to the previous comments, admittedly although deadlock can be prevented it does seem to cross responsibility boundaries. I do not disagree necesarrily that deadlock recovery should be allowed, just that the reference used is not justification enough to do it.
Philippe: In my LockManager implementation, the lock's owner is Thread.currentThread()
Eugene: This is a bad idea. RMI makes no guarantees with respect to mapping remote object invocations to threads. That means that client A may use thread T1 to lock a record, and then use thread T2 to unlock the same record.
Philippe: But I've read over multiple threads here, that if RMI specs "makes no guarantees with respect to mapping remote object invocations to threads", nobody knows any implementation which doesn't.
Svetlana: It's why I so dislike the idea to allow client to lock records remotely.
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Max wrote:
Regardless of where it should be from an aesthetic level, my feeling is that Sun intended for the locking control to reside inside Data, because they put the locking method signature inside the Data class. Thus, I think you're coloring outside the lines a bit if you don't do that. This is just my opinion, of course. But I think Data is really supposed to be your low level DB API.
[SCJP, SCJD]
Originally posted by Patrick Cobbett:
Or are you accessing the static Map in Data directly?
At the moment, my view is that record-locking or indeed lock-recovery should not reside in Data. Data provides primitive record-locking services. Data does not care who is performing lock and unlock operations. This is in accordance with the Data class's provided lock signatures.
When this is born in mind, there is no such thing as dead-lock because Data doesn't know what clients have what locks and which locks they are trying lock. The locking mechanism as seen from the connection layer is built on top of Data's primitive locking mechanism. Therefore it is the responsibility of the network layer to provide the dead-lock recovery which the networking layer itself would need due to concurrent connections.
what is your view on this?
[SCJP, SCJD]
Originally posted by Patrick Cobbett:
Thanks Max. In my assignment FBNS, the Data class declares a method:
lock(int record)
and not
lock(int record, Object src);
Therefore is it reasonable to assume that as i must implement lock(int) then Data is assumed not to know who locks what?
Why is so much reference used to a Map? I may be missing a big point here. I am using an ArrayList to map Connections to RecordLocks. A list is used for an ordered collection referenced by index. If, as in my assignment suggests, we need to lock according to an int index, then doesn't it make sense to use a List? How is the map being implemented? What is being bound to what? I may be missing something here.
thanks in advance
public void lock(int record)
public void unlock(int record)
Record locking must be implemented using the methods public void lock(int) and public void unlock(int). These methods are required to allow concurrent use of the database when booking flights from multiple clients. Note that the locking required is effectively a "write" lock only. If updates occur to a record that is being displayed on another client, then no change occurs at the other client. However, if two clients attempt to perform the sequence lock, read, modify, write, unlock concurrently, then both modification attempts will be handled correctly. The aim is to ensure that if two customers attempt to book a seat on the same flight concurrently, then the number of available seats is definitely reduced by two, unless there was only one seat, in which case, one customer will be advised at booking time that no more seats are available.
The lock method should block until the requested lock can be applied. The integer argument indicates the record to be locked. If the method is called with an argument of -1, the entire database should be locked.
The unlock method simply removes the lock from the specified record. If an attempt is made to unlock a record that has not been locked by this connection, then no action is be taken.
[SCJP, SCJD]
Originally posted by Patrick Cobbett:
This is what my requirements say alot locking..
[qb]
The unlock method simply removes the lock from the specified record. If an attempt is made to unlock a record that has not been locked by this connection, then no action is be taken.
from this last bit, unlock(int) removes the lock from the specified record, irrespective of the invoker? It is the connection layer that ensures that only clients which own a lock may release it.
what do you think?[/QB]
Lock-unlock are too fine grained for remote operation anyway and too dangerous. in real world you'll want to encapsulate it in a database like in Oracle for ex.
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Instructions: If an attempt is made to unlock a record that has not been locked by this connection, then no action is be taken.
Patrick: from this last bit, unlock(int) removes the lock from the specified record, irrespective of the invoker? It is the connection layer that ensures that only clients which own a lock may release it.
Max: IMO, it's highly respective of the user, because the Data.unlock )(emphasis on [d]Data[/b]) method ensure that if a record has not been locked by this connection, then no action is be taken.
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Originally posted by Andrew Monkhouse:
Hi Patrick
Hmm, I read that sentence the same way Patrick did. That sentence is talking about a connection attempting to unlock a record, not the unlock method itself.
The Data class, as provided, has no knowledge of connections.
And I think this is a good thing - it allows for a clear separation of responsibilities: the Data class is only responsible for accessing the database. Then you write network code that handles connections.
And in this networked code you handle ownership of locks issues.
Regards, Andrew
The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Hi Max,
As you say - this is open to interpretation. I don't really disagree with anything you have said, but just to explain my thoughts a bit further ....
We are talking about FBNS here. This is the one where Sun provided the Data class. So we have some limitations. The lock method should be implemented in the Data class or in a class that extends Data.
I don't believe we should be making one instance of Data class per connection.
And the signature for the lock method does not allow any way of indicating the connection. So I don't see how the Data class itself can meet that requirement.
If you have a LockManager as a front end to the Data class (so <client-code> --> <network> --> <LockManager> --> <Data> then it becomes easy. But this does not meet your interpretation that the Data class has to know who owns the lock.
Likewise if you have the connection code itself track which locks it has been granted (one step down from a LockManager) then it is also easy. But again this does not meet your interpretation that the Data class has to know who owns the lock.
Just so we are clear here: when I am talking about connection code, I am talking about the code on the server. I am not talking about code on the client side.
And the signature for the lock method does not allow any way of indicating the connection. So I don't see how the Data class itself can meet that requirement.
[SCJP, SCJD]
Max, I do not deny that Data is where I'd be happiest putting the mapping of connections to record locks. But our requirements does not allow it unless we change the signature of the supplied lock operations.
You say that from an OOD perspective, it makes most sense for the Map to exist as a static member of Data. I feel that the use and referencing of static member variables is not very OOD compliant.
What if we have multiple instances of Data operating on different databases? Surely the record locking mechanisms would get in each other's way?
Also, assuming that this static Map member is at the very most package-private, how could client Java classes written outside the package handle locking correctly?
Politics n. Poly "many" + ticks "blood sucking insects". Tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
|