Session Management in WCS

Posted by Hariharan Vadivelu on
As compared to other commerce engines like ATG and Hybris, WCS takes a different approach of persisting session data in database tables,The idea of managing session related data in database promises very large scale cluster of WCS with minimal overhead on session chattiness across JVM clusters as WCS JVM's need to only make a database roundtrip to read the session state and need not replicate HttpSession Objects, but at times it may cause unnecessary overhead on database tables and thus become a major cause of concern for site stability.

We will review the design and some of the best practices that will ensure a greater site stability.


Design


#1 WCS manages session / context state in the database.

#2 WCS is packaged OOB without any dependency on HttpSession Object, as a best practice it is discouraged to use this during customization as well.

#3 only one active session from any one device or in others words you cannot browse from two different browsers or a browser and device at the same time as a logged in user. The default behavior is to invalidate the session related to the device/browser which was used previously.


#4 When the user state is changed from generic to guest user an entry is created in CTXMGMT and multiple entries will be created in CTXDATA for each context.
E.g.

//One entry is created to track guest user state
INSERT INTO CTXMGMT (ACTIVITY_ID, CALLER_ID, STARTTIME, ENDTIME, STATUS, STORE_ID, RUNAS_ID, LASTACCESSTIME, OPTCOUNTER) VALUES (?(69,751), ?(14,003), ?(10/6/12 10:34 PM), ?(10/6/12 10:34 PM), ?('A'), ?(10,951), ?(14,003), ?(10/6/12 10:34 PM), ?(25,580))

//Multiple entries are created for each context
INSERT INTO CTXDATA (NAME, ACTIVITY_ID, SERVALUE, OPTCOUNTER) VALUES (?('com.ibm.commerce.context.audit.AuditContext'), ?(69,751), ?(null), ?(17,127))

INSERT INTO CTXDATA (NAME, ACTIVITY_ID, SERVALUE, OPTCOUNTER) VALUES (?('com.ibm.commerce.store.facade.server.context.StoreGeoCodeContext'), ?(69,751), ?('null&null&null&null&null&null'), ?(16,630))

INSERT INTO CTXDATA (NAME, ACTIVITY_ID, SERVALUE, OPTCOUNTER) VALUES (?('com.ibm.commerce.catalog.businesscontext.CatalogContext'), ?(69,751), ?('10301&null&false&false&false'), ?(24,205))

INSERT INTO CTXDATA (NAME, ACTIVITY_ID, SERVALUE, OPTCOUNTER) VALUES (?('com.ibm.commerce.context.globalization.GlobalizationContext'), ?(69,751), ?('-1&USD&-1&USD'), ?(9,048))

INSERT INTO CTXDATA (NAME, ACTIVITY_ID, SERVALUE, OPTCOUNTER) VALUES (?('com.ibm.commerce.context.base.BaseContext'), ?(69,751), ?('10951&14003&14003&-1'), ?(21,650))

INSERT INTO CTXDATA (NAME, ACTIVITY_ID, SERVALUE, OPTCOUNTER) VALUES (?('com.ibm.commerce.giftcenter.context.GiftCenterContext'), ?(69,751), ?('null&null&null'), ?(16,598))

INSERT INTO CTXDATA (NAME, ACTIVITY_ID, SERVALUE, OPTCOUNTER) VALUES (?('com.ibm.commerce.context.entitlement.EntitlementContext'), ?(69,751), ?('null&null&null&null&null&null&null'), ?(27,836))


#5 For every Activity as logged in or guest user the CTXDATA table will be updated.

#6 When Guest clicks on Logout the session is terminate as follows.

update ctxmgmt set status = 'T', endtime = ?(10/6/12 10:47 PM), OPTCOUNTER=(CASE WHEN (OPTCOUNTER IS NULL OR OPTCOUNTER=32767) THEN 1 ELSE OPTCOUNTER+1 END) where caller_id = ?(14,004) and status = 'A'

Performance Consideration

Over a period of time IBM has provided several enhancements / fixes for session management to reduce the overall overhead related to database performance. Following is a summary of some of the best practices for production level tuning of these tables.

#1 CTXMGMT and CTXDATA can get excessive entries if you have not taken care of certain things in your code, for instance any command that needs to run as generic user should overwrite isGeneric() method to return true else WCS will try and create a guest ID and thus add a new entry in these tables.
For example browse commands can run as generic users so it is best to overwrite isGeneric() command, the first step should be to perform code review and ensure commands that do not need any session tracking should overwrite isGeneric() method.

Refer this technote for more details.

#2 Try to keep records in this table as low as possible, this should be implemented as part of site database maintenance and DB clean activity.
WCS does provide ActivityCleanup and DBClean scripts for this, but for large scale sites clearing the records from ActivityCleanup Job may turn out
to be an overkill, try to perform this activity when traffic is low to the site.

For example a simpler option is to delete all sessions that have not been accessed for last X Days, in this example it will delete all sessions that were not accessed for last 3 days.

delete from CTXMGMT where (SYSDATE - 3) >= LASTACCESSTIME


#3 CTXMGMT with multiple 'A' entries for same runas_id implies some issues with the code, try to trace the code using server side profiler and take corrective action as needed.

#4 If you see an index block contention on CTXMGMT / CTXDATA from the AWR reports, try to apply reverse key index and retest 
Reverse key index is online activity and it can be applied/reverted back quickly. The problem is quite evident in RAC based database setup where this “hot” index block needs to be accessed by all the instances and is being bounced around the various SGAs causing expensive block transfers between instances.

#5 Fragmentation of index

Since CTXMGMT and CTXDATA relatively has one of the maximum rates of inserts the index can get fragmented fairly quickly, as part of database maintenance activity analyze the index often and re-build as and when needed.
Here is an interesting blog on Oracle on index rebuild.


Rebuild the index as follows, perform these activities when the site has low traffic.

Alter index <index_name> rebuild online; --CTXMGMT TABLE

Reference


Google search with following string to see all technotes related to CTXMGMT
site:http://www-01.ibm.com/support/docview.wss CTXMGMT





6 comments: