Andrea,
You can do this If you create a state object that has an application scope... you can wire your session listener to it to add and remove the session id's.

<state-object name="ApplicationManager" scope="application">

Andrea Chiumenti wrote:
But session is user specific and you want to lock the record accross the
application, how whould you do this ?

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

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]




--
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]

Reply via email to