All,
Please see https://bz.apache.org/bugzilla/show_bug.cgi?id=66513 for
reference.
It appears that the synchronization used by the PersistentManager can
cause problems when used with the PersistentValve and DataSource/JDBCStore.
The problem is that PersistentManager assumes that the Session object
can be used as a synchronization monitor to load/update the session in
the Store. The DataSource/JDBCStore implementation uses an INSERT to
create a new session, and a DELETE-then-INSERT to re-write the session
data in the db.
When two requests arrive simultaneously, thread scheduling can cause
DELETE-then-DELETE-then-INSERT-then-INSERT which causes a duplicate PK
violation.
If the PersistentValve were not in use, the in-memory Session would be
stable. PersistentValve re-loads the Session from the Store on ever
request, rendering the PersistentManager's synchronized(session) attempt
to protect things useless.
I think a simple way to fix this might be to change:
// PersistentManager.java:478~
if(session != null) {
synchronized(session){
session = super.findSession(session.getIdInternal());
if(session != null){
// To keep any external calling code from messing up the
// concurrency.
session.access();
session.endAccess();
}
}
}
to this:
if(session != null) {
sessionId = String.intern(sessionId);
synchronized(sessionId){
session = super.findSession(session.getIdInternal());
if(session != null){
// To keep any external calling code from messing up the
// concurrency.
session.access();
session.endAccess();
}
}
}
This swaps the Session object for the sessionId as the synchronization
monitor. We use String.intern to ensure that we always have the same
exact object, even across sessions, request, etc.
This is *a* way to solve this problem. There are other ways.
Another way is also a TODO in the DataSourceRealm code which suggests
using UPDATE for sessions that already exist. That is probably worth
implementing, and it would fix this particular issue.
Note that it is essentially impossible to prevent thread scheduling,
requests to other members of the cluster, etc. to prevent data-loss from
the session and this BZ isn't asking us to fix that. It's only asking
that a single Tomcat node with PersistentValve enabled doesn't cause
thee duplicate PK violations for some pretty basic usages.
-chris
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org