Actually, no, if the browser dies, the record won't stay locked.
The updating happens from the edit page; if the browser crashes, there's no edit page, so no updating, so the lock expires.

Cheers,

Robert

On Feb 21, 2007, at 2/214:03 AM , Andrea Chiumenti wrote:

... But if the browser dies for some reason (very frequent especially with MS products), then the record will remain locked, the only possibility with this solution would be to add a locking timeout with application scope.

On 2/21/07, Robert Zeigler <[EMAIL PROTECTED]> wrote:

In my case, it was straightforward: the user is considered to be
"still editing" if they have a browser window open to the edit page
for the object in question; if they navigate away from that page, the
system considers their edit session over.

Robert


On Feb 21, 2007, at 2/212:47 AM , Peter Stavrinides wrote:

> Hi Robert
>
> I like your idea, "you say that periodic ajax calls are sent to the
> server to inform of the fact that the user is still editing" how
> exactly do you track if a user is still editing?
>
> Robert Zeigler wrote:
>> The main problem with using a session timeout for the lock is that
>> it doesn't allow you to detect events where a user starts to edit
>> an object, does not finish, but remains active in the webapp; the
>> session won't die, and neither will your lock. You have to
>> incorporate time at least to some degree. I implemented similar
>> functionality in an application recently, but used a bit of ajax
>> magic to ensure that the lock was held for exactly as long as it
>> needed to be and no longer (while the user is editing the object,
>> periodic ajax calls are sent to the server to inform of the fact
>> that the user is still editing; if the user saves, the lock is
>> released; if the user moves to a different portion of the webapp
>> without saving or canceling the lock, the lock expires since there
>> are no more ajax calls to keep the lock valid)
>>
>> Robert
>>
>> On Feb 21, 2007, at 2/211:56 AM , Peter Stavrinides wrote:
>>
>>> I don't think the benefits justify the effort involved to
>>> maintain all those timestamps, its a bit too complex. Perhaps its
>>> better to stick to a single table as well... rather write the
>>> session id into the database to checkout a customer record.
>>>
>>> Allow updates to a customer record if its not checked out, and
>>> this way you have no worries about lock expiration etc.
>>>
>>> You should maintain an ASO that tracks all active sessions by
>>> session id. Once a user queries for a customer record that has
>>> been checked out, if the session ID still exists in the ASO, then
>>> refuse update access and grant only read access, simple and
>>> elegant. Once the user saves successfully release the lock in the
>>> database. if a session is interrupted for whatever reason, then
>>> using a session timeout of 20 or 30 minutes and a session
>>> listener you clean up removing the session ID from the ASO and
>>> database... so you are well covered. I am no guru like some of
>>> these other guys, but this works for me and its nice and
>>> simple... here is a brief implementation outline:
>>>
>>> public class ApplicationManager {
>>>
>>> /** variable to store the singleton ApplicationManager */
>>> private static final ApplicationManager
>>> applicationManagerInstance_ = new ApplicationManager();
>>>
>>> /** Hashtable containing visit history objects. <String,Visit> is
>>> the sessionid and the Visit Object */
>>> private static ConcurrentHashMap<String,Visit> visitHistory_ =
>>> new ConcurrentHashMap<String,Visit>();
>>>
>>> /** @return the ApplicationManager instance */
>>> public synchronized static ApplicationManager getInstance(){
>>> return applicationManagerInstance_;
>>> }
>>>
>>> }
>>>
>>> public class SessionMonitor implements HttpSessionListener {
>>>
>>> /** @see javax.servlet.http.HttpSessionListener#sessionDestroyed
>>> (javax.servlet.http.HttpSessionEvent) */
>>> public void sessionDestroyed(HttpSessionEvent event) {
>>> String sid = event.getSession().getId();
>>> ApplicationManager manager = ApplicationManager.getInstance();
>>> manager.removeUserSession(sid);
>>> }
>>>
>>>
>>> Hivemodule.xml:
>>>
>>> <contribution configuration- id="tapestry.state.ApplicationObjects">
>>> <state-object name="visit" scope="session">
>>> <create-instance class="application.Visit"/>
>>> </state-object>
>>> </contribution>
>>>
>>> <contribution configuration- id="tapestry.state.ApplicationObjects">
>>> <state-object name="ApplicationManager" scope="application">
>>> <create-instance class="application.ApplicationManager"/>
>>> </state-object>
>>> </contribution>
>>>
>>> cheers,
>>> Peter
>>>
>>> Murray Collingwood wrote:
>>>> Wow - what a lot of responses.
>>>>
>>>> First a little more detail - use case (for example):
>>>>
>>>> Take a customer record, a basic record has previously been
>>>> created and the
>>>> customer has completed some forms so we are now wanting to
>>>> complete all of the
>>>> details about contact information, financial details, key
>>>> assets, health
>>>> information, etc, etc. The system relies on a number of
>>>> classifications which
>>>> need to be looked up, anyways, editing this record can take upto
>>>> 20 minutes. The size of this record certainly justifies breaking
>>>> it up into a number of
>>>> smaller records stored in separate tables, however the same
>>>> problem remains
>>>> because the user wants to see all of this information on 1
>>>> (scrollable) web
>>>> page, we are still holding a lock on the information for the
>>>> duration of the
>>>> request.
>>>>
>>>> Potentially there are maybe 700 people who could be editing this
>>>> record for
>>>> different reasons. Accuracy of the information is critical - we
>>>> don't want
>>>> personal details being sent to a neighbour.
>>>>
>>>> The nature of the application means that users will be reviewing
>>>> a record each
>>>> year, and if any changes are made they are often made to the
>>>> same record around
>>>> the same time of the year - increasing the possibility of two
>>>> people wanting to
>>>> edit the record at the same time.
>>>>
>>>> Besides all of the above, the user has asked for exclusive
>>>> editing of a record -
>>>> such that other users can still read the existing record but
>>>> nobody else can
>>>> update the record while it is locked. The user understands the
>>>> concept of
>>>> networks issues and broken connections and therefore accepts a
>>>> timeout condition
>>>> on the lock of say 20 minutes.
>>>>
>>>> Next, how I will do this:
>>>>
>>>> 1. To establish a lock:
>>>> a. I need a LOCK table: foreign-key, timestamp, userid
>>>> b. In my Session I need a collection of timestamps
>>>> c. Create a timestamp value - add it to my collection of timestamps
>>>> d. Add a record to the LOCK table using my timestamp value
>>>> e. Select from the lock table by foreign-key - if mine is the
>>>> only record then
>>>> read the record and begin editing, the lock was successful
>>>>
>>>> 2. Release the lock: (PS This is the difficult bit)
>>>> a. Retrieve the LOCK records by foreign-key and userid,
>>>> hopefully there should
>>>> only be one.
>>>> b. Check the timestamp value against my Session collection of
>>>> timestamp values
>>>> c. If the timestamp is in my collection then save the edited
>>>> record and delete
>>>> my LOCK record
>>>> d. If the timestamp is not in my collection then the save has
>>>> failed - tell the
>>>> user gently
>>>>
>>>> 3. Dealing with an existing lock:
>>>> a. While trying to establish a lock I find 2 LOCK records
>>>> b. The latest record is mine, ignore that and look at the
>>>> earlier record
>>>> c. Look at the timestamp on the earlier record, if older than 20
>>>> minutes then
>>>> delete this record and continue as normal
>>>> d. Look at the userid on the earlier record, if it is mine then
>>>> delete it and
>>>> continue as normal (assumes my browser died, rebooted my
>>>> computer, whatever,
>>>> it's very typical for people to go straight back to what they
>>>> were doing when
>>>> their system crashed)
>>>> e. If the timestamp is less than 20 minutes old then delete my
>>>> LOCK record and
>>>> report to the user that the record is locked by another user
>>>>
>>>> 4. You may want a maintenance process that cleans up broken
>>>> locks, automatically
>>>> deleting locks with a timestamp older than 24 hours. You could
>>>> schedule this
>>>> nightly or weekly - it's not critical.
>>>>
>>>>
>>>> Why the collection of timestamps?
>>>>
>>>> 1. It allows the user to use the back button on the browser,
>>>> either during
>>>> editing or after editing (if it didn't save correctly the first
>>>> time).
>>>>
>>>> 2. They might need to edit a related record in a different table
>>>> as part of
>>>> updating the main record - by storing each timestamp in a
>>>> session collection we
>>>> don't need to maintain these timestamps on our forms.
>>>>
>>>>
>>>> Why add the lock record first?
>>>>
>>>> To avoid sequence problems like:
>>>> a: User 1 looks for lock on id=1 - none found
>>>> b: User 2 looks for lock on id=1 - none found
>>>> c: User 1 adds a lock record
>>>> d: user 2 adds a lock record
>>>> Now the worst possible outcome is:
>>>> a: User 1 adds a lock record on id=1
>>>> b: User 2 adds a lock record on id=1
>>>> c: Both users read and find two records with short timestamps -
>>>> they are both
>>>> informed the record is in use and to try again later - both
>>>> records are deleted.
>>>>
>>>>
>>>> Finally - the weakness:
>>>>
>>>> 1. The lock this gives you is only guaranteed for 20 minutes.
>>>> Once that time is
>>>> up somebody else can overwrite your lock with their own. It is
>>>> better to set
>>>> this timeout higher rather than lower.
>>>>
>>>> 2. You can overwrite your own lock. A user could open two
>>>> browsers and edit the
>>>> same record in each, the latter save overwriting the first.
>>>> Hmmm, I think this
>>>> comes under 'user error'.
>>>>
>>>>
>>>> I think that explains it fairly well.
>>>>
>>>> Cheers
>>>> mc
>>>>
>>>>
>>>>
>>>> -------------------------------------------------------------------
>>>> --
>>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>>>> For additional commands, e-mail: [EMAIL PROTECTED]
>>>>
>>>>
>>>
>>> --Peter Stavrinides
>>> Albourne Partners (Cyprus) Ltd
>>> Tel: +357 22 750652
>>> If you are not an intended recipient of this e-mail, please
>>> notify the sender, delete it and do not read, act upon, print,
>>> disclose, copy, retain or redistribute it. Please visit http://
>>> www.albourne.com/email.html for important additional terms
>>> relating to this e-mail.
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [EMAIL PROTECTED]
>> For additional commands, e-mail: [EMAIL PROTECTED]
>>
>
> --
> Peter Stavrinides
> Albourne Partners (Cyprus) Ltd
> Tel: +357 22 750652
> If you are not an intended recipient of this e-mail, please notify
> the sender, delete it and do not read, act upon, print, disclose,
> copy, retain or redistribute it. Please visit http://
> www.albourne.com/email.html for important additional terms relating
> to this e-mail.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to