> From: "David Whitehurst" <[EMAIL PROTECTED]>
> Sent: Wednesday, April 27, 2005 9:15 AM

> Will , I do editing application software for clients like BMW and
> Volkswagen, and my application had an issue where e.g. 2 records in
> 22,000 edits had the same data tied to different keys and different
> editors (users).  I found that I was using a HashMap (not threadsafe,
> changed that) and I now ..I am wondering whether the use of java simple
> types (e.g. client, and user strings) in the session is a good idea.

Well, let's look at the problem.

Sessions are based on a JSESSIONID (typically) which is assigned to the user
when the session is created.

In a perfect world, the user will only be making a single, synchronous
requests to the server (meaning they'll happily wait until the request
returns before making another request). But, it's important to know simply
that sessions are tied to requests, so if you have several simultaneous
requests with the same JSESSIONID, then you have a race condition whenver
you interact with sessions (or any objects taken from sessions, for that
matter).

Next, though, is the Request itself. Requests are just like Sessions, in
that they can have arbitrary attributes. However, requests are unique. You
may get several simultaneous Requests all within the same Session, but they
all are unique Requests. So, modulo jumping through hoops to change the
behavior, you shouldn't have to synchronize anything when dealing with a
Request, or any attribute placed in it. Note, that sticking an object
fetched from a Session and placing it in the Request doesn't suddenly free
it if there's a chance another thread can get the same object from the same
Session.

If you're using the Session as a big global space to pass things around to
routines within the application, then you most certainly need to synchronize
access to those objects.

However, you mention that your behavior was manifesting across USERS. All of
those users should have their own unique Sessions.

So the question becomes, how did these Users get the same Object placed into
their Session?

A wild guess would be from a central cache.

Perhaps when you fetch a record, you cache it, and then return that
structure to the User, who then stuffs it into their Session for
manipulating. If another User accesses the same record, they may well get
the exact same object from the cache, and now you have two Users fighting
over the same object. You would get this even if access to the cache itself
is synchronized, as it doesn't effect the root object in question, just who
gets it first.

Here, you need to think about either cloning (to some arbitrary depth) your
cached object before returning them to the requestor, or just creating them
new copies.

Also, this suggests that you may have an even deeper problem of locking on
the database end. It sounds like you may have an issue that even if you get
two seperate copies for your two Users, you may well have the issue of one
user stomping on the changes of another. Most folks today use some scheme
for optimistic locking using a row version number, or timestamp, and making
sure that the version of the row you're updating in the database is the same
as the one you have, if not you can handle it however you want (note, this
can be the tricky part).

Now, none of this has anything to do with serialization. In fact,
serializing the object ends up creating new objects that are essentially not
shared. If two Users are sharing an object, and their Sessions get persisted
and then reloaded, they both end up with 2 new distinct objects, where they
shared one before.

As far as the basic Java types, Strings are immutable. Period. That's
enforced by the JVM. You can't change one behind the back of another user.
No race conditions with Strings themselves.

The real primitives (int, byte, char, etc.) are immutable. You can have two
threads trying to change the value of a primitive member variable of an
object, but that's the objects problem, not the primitives. If two threads
fight over the same primitive, one will win, and win completely. I don't
think you'll get half one int, and half of another int, but that's really up
to the CPU architecture as well as the JVM. (For example, I don't know if
you atomically assign a long (64-bit) value without the risk of it being
interuppted in the middle. I don't even know if Java can interrupt a thread
in the middle of a byte code execution or not (assuming byte codes are
atomic)). Frankly, I wouldn't worry about these at all.

The Java Objects like Integer, Boolean, etc, are EFFECTIVELY immutable, but
there's a catch. The methods on, say, Integer, don't allow you to change the
value of an Integer once it is constructed, but if you're playing some games
with introspection and reflection, it CAN be done. It, as a rule, isn't, but
it IS possible. I wouldn't worry about these either.

So, basically, it's the containers and regular classes you need to worry
about, and not the primitives themselves.

I would focus on a) how did two users get the same Object in their session
or b) how are users making multiple requests on the same session (why are
they doing this, is it common, etc.).

The problem isn't in the Session itself, nor necessarily in the corrupted
Object, but I think it's deeper in your application wherever you end up
getting your Object.

Knowing essentially nothing about your app, that's the best 2 cents I can
give at this point. I wouldn't worry at all about using the primitve types
(including String) in a Session. Note, though, that Dates don't count.

Regards,

Will Hartung
([EMAIL PROTECTED])




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

Reply via email to