A.2. Persistent object stores

This section briefly describes the characteristics and optimisations of each of the supplied implementations of the persistent object store. Persistent object states are mapped onto the structure of the file system supported by the host operating system.
Common functionality

In addition to the features mentioned earlier all of the supplied persistent object stores obey the following rules:

  • Each object state is stored in its own file that is named using the Uid of the object.
  • The type of an object (as given by the type() operation) determines the directory into which the object is placed.
  • All of the stores have a common root directory that is determined when JBossTS is configured. This directory name is automatically prepended to any store specific root information.
  • All stores also have the notion of a localised root directory that is automatically prepended to the type of the object to determine the ultimate directory name. The localised root name is specified when the store is created. By default the localised root name is defaultStore.
<ObjectStore root Directory from configure>	/JBossTS/ObjectStore/
	<ObjectStore Type1>			FragmentedStore/
		<Default root>			defaultStore/
			<StateManager>			StateManager
				<LockManager>			LockManager/
					<User Types>		
	<Localised root 2>		myStore/
		<StateManager>			StateManager/
									
	<ObjectStore Type2>		ActionStore/
		<Default root>			defaultStore/
The shadowing store

This is the original version of the object store as provided in prior releases and is implemented by the class ShadowingStore. It is simple but slow. It uses pairs of files to represent objects (the shadow version and the committed version) and files are opened, locked, operated upon, unlocked and closed on every interaction with the object store. Thus significant portions of time can be spent in the system simply opening, closing and renaming files, all of which are very expensive operations.

If overriding the object store implementation, the type of this object store is ShadowingStore.
No file-level locking

Since transactional objects are concurrency controlled through LockManager, it is not necessary to impose additional locking at the file level, as the basic ShadowingStore implementation does. Therefore, the default object store implementation for JBossTS, ShadowNoFileLockStore, relies upon user-level locking. This enables it to provide better performance than the ShadowingStore implementation.

If overriding the object store implementation, the type of this object store is ShadowNoFileLockStore.
The hashed store

The HashedStore has the same structure for object states as the shadowing stores but has an alternate directory structure that is better suited to storing large numbers of objects of the same type. Using this store objects are scattered amongst a set of directories by applying a hashing function to the object's Uid. By default 255 sub-directories are used. However, this can be overridden by setting the HASHED_DIRECTORIES environment variable accordingly.

If overriding the object store implementation, the type of this object store is HashedStore.
No file-level locking

Since transactional objects are concurrency controlled through LockManager, it is not necessary to impose additional locking at the file level, as the basic ShadowingStore implementation does. Therefore, the default object store implementation for JBossTS, ShadowNoFileLockStore, relies upon user-level locking. This enables it to provide better performance than the ShadowingStore implementation.

If overriding the object store implementation, the type of this object store is ShadowNoFileLockStore.
The hashed store

The HashedStore has the same structure for object states as the shadowing stores but has an alternate directory structure that is better suited to storing large numbers of objects of the same type. Using this store objects are scattered amongst a set of directories by applying a hashing function to the object's Uid. By default 255 sub-directories are used. However, this can be overridden by setting the HASHED_DIRECTORIES environment variable accordingly.

If overriding the object store implementation, the type of this object store is HashedStore.
The JDBC store

The JDBCStore uses a JDBC database to save persistent object states; when used in conjunction with the Transactional Objects for Java API nested transaction support is available. In the current implementation, all object states are stored as Binary Large Objects (BLOBs) within the same table. The limitation on object state size imposed by using BLOBs is 64k; if an attempt is made to store an object state which exceeds this limit an error will be output and the state will not be stored. The transaction will subsequently be forced to roll back.

When using the JDBC object store, the application must provide an implementation of the following interface, located in the com.arjuna.ats.arjuna.objectstore package:
public interface JDBCAccess
{
	public Connection getConnection () throws SQLException;
	public void putConnection (Connection conn) throws SQLException;
	public void initialise (ObjectName objName);
}
The implementation of this class is responsible for providing the Connection which the JDBC ObjectStore will use to save and restore object states:
  • getConnection: returns the Connection to use. This method will be called whenever a connection is required and the implementation should use whatever policy is necessary for determining what connection to return. This method need not return the same Connection instance more than once.
  • putConnection: this method will be called to return one of the Connections acquired from getConnection. Connections are returned if any errors occur when using them.
  • initialise: this can be used to pass additional arbitrary information to the implementation.
The JDBC object store will initially request the number of Connections defined in the com.arjuna.ats.arjuna.objectstore.jdbcPoolSizeInitial property and will use no more than defined in the com.arjuna.ats.arjuna.objectstore.jdbcPoolSizeMaximum property.
The implementation of the JDBCAccess interface to use should be set in the com.arjuna.ats.arjuna.objectstore.jdbcUserDbAccess property variable.
If overriding the object store implementation, the type of this object store is JDBCStore.
A JDBC object store can be used for managing the transaction log. In this case, the transaction log implementation should be set to JDBCActionStore and the JDBCAccess implementation must be provided via the com.arjuna.ats.arjuna.objectstore.jdbcTxDbAccess property variable. In this case, the default table name is JBossTSTxTable.

Note

It is possible to use the same JDBCAccess implementation for both the user object store and also the transaction log.
The cached store

This object store used the hashed object store, but does not read or write states to the persistent backing store immediately. It maintains the states in a volatile memory cache and either flushes the cache periodically or when it is full. The failure semantics associated with this object store are different to the normal persistent object stores, because a failure could result in states in the cache being lost.

If overriding the object store implementation, the type of this object store is CachedStore.
The store can be configured with the following properties:
  • com.arjuna.ats.internal.arjuna.objectstore.cacheStore.hash sets the number of internal stores to hash the states over. The default value is 128.
  • com.arjuna.ats.internal.arjuna.objectstore.cacheStore.size is the maximum size the cache can reach before a flush is triggered. The default is 10240 bytes.
  • com.arjuna.ats.internal.arjuna.objectstore.cacheStore.removedItems is the maximum number of removed items that the cache can contain before a flush is triggered. By default, calls to remove a state that is in the cache will simply remove the state from the cache, but leave a blank entry (rather than remove the entry immediately, which would affect the performance of the cache). When triggered, these entries are removed from the cache. The default value is twice the size of the hash.
  • com.arjuna.ats.internal.arjuna.objectstore.cacheStore.workItems is the maximum number of items that are allowed to build up in the cache before it is flushed. The default value is 100.
  • com.arjuna.ats.internal.arjuna.objectstore.cacheStore.scanPeriod sets the time in milliseconds for periodically flushing the cache. The default is 120 seconds.
  • com.arjuna.ats.internal.arjuna.objectstore.cacheStore.sync determines whether flushes of the cache are sync-ed to disk. The default is OFF. To enable, set to ON.