Tomcat 7 JDBC Session Persistence

The default Tomcat session management strategy is in-memory session persisted into file when the server is shutdown gracefully. If the server dies in a cold fashion (eg: kill -9 or power outage), session data might be lost. One approach to mitigate this is to store session data into database using JDBC, aka JDBC Session Persistence.

JDBC Session Persistence can also aid load balancer failover scenario. I’d say this is an alternative to setting up (often cumbersome) TCP session replication. Note that if you have multiple cloud servers like Amazon EC2 it doesn’t come with TCP multicast feature — TCP session replication sounds like a nightmare to setup.

The Steps

  1. Ensure org.apache.catalina.session.StandardSession.ACTIVITY_CHECK or org.apache.catalina.STRICT_SERVLET_COMPLIANCE is set to true. Add line similar to following into your Tomcat’s startup.sh (if you’re on UNIX)
    export CATALINA_OPTS="-Dorg.apache.catalina.session.StandardSession.ACTIVITY_CHECK=true"

    Tomcat System Property Reference will explain what do each property means if you’re curious

  2. Create following SQL table (yes you need a database to store the session data)
    create table tomcat_sessions (
      session_id     varchar(100) not null primary key,
      valid_session  char(1) not null,
      max_inactive   int not null,
      last_access    bigint not null,
      app_name       varchar(255),
      session_data   mediumblob,
      KEY kapp_name(app_name)
    );
    
  3. Place a copy of mysql-connector-java.jar (or your DB’s JDBC driver) into $CATALINA_HOME/lib
  4. In your web app, add a META-INF/context.xml file. If you use standard maven layout you have to place it on src/main/webapp/META-INF/context.xml. You can copy the file from $CATALINA_HOME/conf/context.xml as a starting point. Then under element add following element
    
      
    
    

    Notice how the SQL column name corresponds to some of the settings above. In this configuration I used mysql database on localhost with database name “mytomcat” and username “root”. maxIdleBackup=”10″ specifies number of seconds before the in-memory session data is persisted into database.

    There are many other settings you can tweak, have a look at the Tomcat Manager Component Reference.

Fine Prints

This article is tested against Tomcat 7.0.39 but I guess it should also work with Tomcat 6. If you’ve jumped the ship from relational to MongoDB, . I haven’t got a chance to try it but it looks awesome.

6 thoughts on “Tomcat 7 JDBC Session Persistence”

  1. Hello, i have followed your instructions and i am not able to get mysql connection
    Tomcat version is 7.0.55
    mysql version is 5.6
    OS is windows 7

    Heres the log of the localhost.log
    org.apache.catalina.session.JDBCStore getConnection
    SEVERE: A SQL exception occurred java.sql.SQLException: Access denied for user ‘persist’@’localhost’ (using password: YES)

    I am able to login through command prompt. i have set the catalina opts in the catalina.bat also as
    set “CATALINA_OPTS=%CATALINA_OPTS% -Dfile.encoding=UTF8 -Dorg.apache.catalina.STRICT_SERVLET_COMPLIANCE=true -Dorg.apache.catalina.session.StandardSession.ACTIVITY_CHECK=true

    Any help would be greatfull…

    Thanks

    Reply
    1. Probably you forgot to specify the password on the connection URL eg:connectionURL="jdbc:mysql://localhost/mytomcat?user=root&password=s3cret". Not sure if there’s more secure way to set the password. In my example my local mysql root account didn’t require password, hence I didn’t put it

  2. This works as expected for me, except that my sessions time out (or are destroyed) after about 30 seconds. Doesn’t matter what I set my session-timeout values to. Same thing happened on two servers. Any guidance?

    Reply
    1. Maybe your session hasn’t persist through to database before the cold node is hit. The use of this setup normally involves load balancer with session-stickiness — requests coming from the same session always hit the same node

Leave a Reply