https://bz.apache.org/bugzilla/show_bug.cgi?id=66513

Christopher Schultz <ch...@christopherschultz.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |NEEDINFO

--- Comment #1 from Christopher Schultz <ch...@christopherschultz.net> ---
The synchronization in PersistentManager and DataSourceStore/JDBCStore appear
to be reasonable. The session itself is being used as the monitor and not an
arbitrary object stored within the session, which might have been a problem.

I think your problem is not multiple simultaneous requests on a single node
(which ought to be safe), but multiple simultaneous requests across more than
one node.

When saving the session, DataSourceStore/JDBCStore will DELETE the existing
session record and INSERT a new record in its place. This does not happen in a
transaction and therefore it's possible for two nodes in the group to execute
this series of queries:

Node A: DELETE FROM sessions...
Node B: DELETE FROM sessions...
Node A: INSERT INTO sessions...
Node B: INSERT INTO sessions...

This could be fixed with a transaction which surrounds the DELETE and
subsequent INSERT.

It could also be fixed with, as a TODO in the code suggests, using an UPDATE if
the record already exists. (IMHO this is much better for performance as fewer
indexes, etc. would need to be updated when saving a session.)

But there is another problem: even if the database synchronization issues are
resolved, you may find that you have replaced the problem with a race-condition
within your own application. Let's say the following situation occurs
(paraphrasing):

Node A: session.setAttribute("counts", session.getAttribute("counts") + 1);
Node B: session.setAttribute("counts", session.getAttribute("counts") + 1);
Node B: BEGIN ; DELETE ; INSERT
Node A: BEGIN ; DELETE ; INSERT

One of the increments has been lost -- the increment from node B. You can
abstract this to *any* change to the session, since Tomcat saves the session
all at once and not as individual records e.g. for each attribute. The same can
be true if Node A adds a new attribute to the session and Node B adds a
different one.

If the sessions ever disagree about the contents of the session, some session
data will be lost. It is very difficult to completely prevent this kind of
thing from happening given the architecture of the DataSourceStore/JDBCStore.

In light of this, do you think that either using a transaction or switching to
an INSERT ... ON UPDATE type of behavior would resolve this problem for you in
a satisfactory way? If your sessions are colliding in the db itself but you
aren't worried about conflicting data, then either of these solutions will
probably work for you.

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to