JBoss.orgCommunity Documentation
What LockManager does?
In general, LockManager stores lock objects, so it can give Lock object or can release it, etc.
Also, LockManager is responsible for removing Locks that live too long. This parameter may be configured with "time-out" property.
JCR provide two base implementation of LockManager:
org.exoplatform.services.jcr.impl.core.lock.LockManagerImpl
;
org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl
;
In this article, we will talk mostly about CacheableLockManagerImpl.
You can enable LockManager by adding lock-manager-configuration to workspace-configuration.
For example:
<workspace name="ws"> ... <lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl"> <properties> <property name="time-out" value="15m" /> ... </properties> </lock-manager> ... </workspace>
LockManagerImpl is simple implementation of LockManager, and also faster than CacheableLockManager. It stores Lock objects in HashMap and may also persist Locks if LockPersister is configured. LockManagerImpl does not support replication in any way.
See more about LockManager Configuration at here.
CacheableLockManagerImpl stores Lock object in JBoss-cache, so Locks are replicable and affects on cluster, not only a single node. Also JBoss-cache has JDBCCacheLoader, so locks will be stored to database.
Both implementation supports Expired Locks removing. There is LockRemover - separate thread, that periodically ask LockManager for Locks that live much and must be removed. So, timeout for LockRemover may be set as follows, default value is 30m.
<properties> <property name="time-out" value="10m" /> ... </properties>
Replication requirements are the same for Cache
You can see a full JCR configuration example at here.
Common tips:
clusterName
("jbosscache-cluster-name")
must be unique;
cache.jdbc.table.name
must be unique
per datasource;
cache.jdbc.fqn.type
must and
cache.jdbc.node.type must be configured according to used
database;
There is a few ways to configure CacheableLockManagerImpl, and all of them configure JBoss-cache and JDBCCacheLoader.
See http://community.jboss.org/wiki/JBossCacheJDBCCacheLoader
First one is - put JbossCache configuraion file path to CacheableLockManagerImpl
This configuration is not so good as you can think. Because repository may contain many workspaces, and each workspace must contain LockManager configuration, and LockManager config may contain JbossCache config file. So total configuration is growing up. But it is usefull if we want a single LockManager with special configuration.
Config is:
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl"> <properties> <property name="time-out" value="15m" /> <property name="jbosscache-configuration" value="conf/standalone/cluster/test-jbosscache-lock-config.xml" /> </properties> </lock-manager>
test-jbosscache-lock-config.xml
<?xml version="1.0" encoding="UTF-8"?> <jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.2"> <locking useLockStriping="false" concurrencyLevel="50000" lockParentForChildInsertRemove="false" lockAcquisitionTimeout="20000" /> <clustering mode="replication" clusterName="JBoss-Cache-Lock-Cluster_Name"> <stateRetrieval timeout="20000" fetchInMemoryState="false" nonBlocking="true" /> <jgroupsConfig> <TCP bind_addr="127.0.0.1" start_port="9800" loopback="true" recv_buf_size="20000000" send_buf_size="640000" discard_incompatible_packets="true" max_bundle_size="64000" max_bundle_timeout="30" use_incoming_packet_handler="true" enable_bundling="false" use_send_queues="false" sock_conn_timeout="300" skip_suspected_members="true" use_concurrent_stack="true" thread_pool.enabled="true" thread_pool.min_threads="1" thread_pool.max_threads="25" thread_pool.keep_alive_time="5000" thread_pool.queue_enabled="false" thread_pool.queue_max_size="100" thread_pool.rejection_policy="run" oob_thread_pool.enabled="true" oob_thread_pool.min_threads="1" oob_thread_pool.max_threads="8" oob_thread_pool.keep_alive_time="5000" oob_thread_pool.queue_enabled="false" oob_thread_pool.queue_max_size="100" oob_thread_pool.rejection_policy="run" /> <MPING timeout="2000" num_initial_members="2" mcast_port="34540" bind_addr="127.0.0.1" mcast_addr="224.0.0.1" /> <MERGE2 max_interval="30000" min_interval="10000" /> <FD_SOCK /> <FD max_tries="5" shun="true" timeout="10000" /> <VERIFY_SUSPECT timeout="1500" /> <pbcast.NAKACK discard_delivered_msgs="true" gc_lag="0" retransmit_timeout="300,600,1200,2400,4800" use_mcast_xmit="false" /> <UNICAST timeout="300,600,1200,2400,3600" /> <pbcast.STABLE desired_avg_gossip="50000" max_bytes="400000" stability_delay="1000" /> <pbcast.GMS join_timeout="5000" print_local_addr="true" shun="false" view_ack_collection_timeout="5000" view_bundling="true" /> <FRAG2 frag_size="60000" /> <pbcast.STREAMING_STATE_TRANSFER /> <pbcast.FLUSH timeout="0" /> </jgroupsConfig <sync /> </clustering> <loaders passivation="false" shared="true"> <preload> <node fqn="/" /> </preload> <loader class="org.jboss.cache.loader.JDBCCacheLoader" async="false" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false"> <properties> cache.jdbc.table.name=jcrlocks_ws cache.jdbc.table.create=true cache.jdbc.table.drop=false cache.jdbc.table.primarykey=jcrlocks_ws_pk cache.jdbc.fqn.column=fqn cache.jdbc.fqn.type=VARCHAR(512) cache.jdbc.node.column=node cache.jdbc.node.type=<BLOB> cache.jdbc.parent.column=parent cache.jdbc.datasource=jdbcjcr </properties> </loader> </loaders> </jbosscache>
Configuration requirements:
<clustering mode="replication" clusterName="JBoss-Cache-Lock-Cluster_Name"> - cluster name must be unique;
cache.jdbc.table.name
must be unique
per datasource;
cache.jdbc.node.type
and
cache.jdbc.fqn.type
must be configured
according to using database. See Data Types in Different Databases .
Second one is using template JBoss-cache configuration for all LockManagers
Lock template configuration
test-jbosscache-lock.xml
<?xml version="1.0" encoding="UTF-8"?> <jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.1"> <locking useLockStriping="false" concurrencyLevel="50000" lockParentForChildInsertRemove="false" lockAcquisitionTimeout="20000" /> <clustering mode="replication" clusterName="${jbosscache-cluster-name}"> <stateRetrieval timeout="20000" fetchInMemoryState="false" /> <jgroupsConfig multiplexerStack="jcr.stack" /> <sync /> </clustering> <loaders passivation="false" shared="true"> <!-- All the data of the JCR locks needs to be loaded at startup --> <preload> <node fqn="/" /> </preload> <!-- For another cache-loader class you should use another template with cache-loader specific parameters -> <loader class="org.jboss.cache.loader.JDBCCacheLoader" async=q"false" fetchPersistentState="false" ignoreModifications="false" purgeOnStartup="false"> <properties> cache.jdbc.table.name=${jbosscache-cl-cache.jdbc.table.name} cache.jdbc.table.create=${jbosscache-cl-cache.jdbc.table.create} cache.jdbc.table.drop=${jbosscache-cl-cache.jdbc.table.drop} cache.jdbc.table.primarykey=${jbosscache-cl-cache.jdbc.table.primarykey} cache.jdbc.fqn.column=${jbosscache-cl-cache.jdbc.fqn.column} cache.jdbc.fqn.type=${jbosscache-cl-cache.jdbc.fqn.type} cache.jdbc.node.column=${jbosscache-cl-cache.jdbc.node.column} cache.jdbc.node.type=${jbosscache-cl-cache.jdbc.node.type} cache.jdbc.parent.column=${jbosscache-cl-cache.jdbc.parent.column} cache.jdbc.datasource=${jbosscache-cl-cache.jdbc.datasource} </properties> </loader> </loaders> </jbosscache>
As you see, all configurable paramaters are filled by templates and will be replaced by LockManagers conf parameters:
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl"> <properties> <property name="time-out" value="15m" /> <property name="jbosscache-configuration" value="test-jbosscache-lock.xml" /> <property name="jgroups-configuration" value="udp-mux.xml" /> <property name="jgroups-multiplexer-stack" value="true" /> <property name="jbosscache-cluster-name" value="JCR-cluster-locks-ws" /> <property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks_ws" /> <property name="jbosscache-cl-cache.jdbc.table.create" value="true" /> <property name="jbosscache-cl-cache.jdbc.table.drop" value="false" /> <property name="jbosscache-cl-cache.jdbc.table.primarykey" value="jcrlocks_ws_pk" /> <property name="jbosscache-cl-cache.jdbc.fqn.column" value="fqn" /> <property name="jbosscache-cl-cache.jdbc.fqn.type" value="AUTO"/> <property name="jbosscache-cl-cache.jdbc.node.column" value="node" /> <property name="jbosscache-cl-cache.jdbc.node.type" value="AUTO"/> <property name="jbosscache-cl-cache.jdbc.parent.column" value="parent" /> <property name="jbosscache-cl-cache.jdbc.datasource" value="jdbcjcr" /> </properties> </lock-manager>
Configuration requirements:
jbosscache-cl-cache.jdbc.fqn.column
and jbosscache-cl-cache.jdbc.node.type
is
nothing else as cache.jdbc.fqn.type and cache.jdbc.node.type in
JBoss-Cache configuration. You can set those data types according
to database type (See Data Types in Different Databases) or set it as AUTO (or do not set at
all) and data type will by detected automaticaly.
As you see, jgroups-configuration moved to separate config file - udp-mux.xml; In our case udp-mux.xml is common JGroup config for all components (QueryHandler, cache, LockManager). But we can still create own config.
our-udp-mux.xml
<protocol_stacks> <stack name="jcr.stack"> <config> <UDP mcast_addr="228.10.10.10" mcast_port="45588" tos="8" ucast_recv_buf_size="20000000" ucast_send_buf_size="640000" mcast_recv_buf_size="25000000" mcast_send_buf_size="640000" loopback="false" discard_incompatible_packets="true" max_bundle_size="64000" max_bundle_timeout="30" use_incoming_packet_handler="true" ip_ttl="2" enable_bundling="true" enable_diagnostics="true" thread_naming_pattern="cl" use_concurrent_stack="true" thread_pool.enabled="true" thread_pool.min_threads="2" thread_pool.max_threads="8" thread_pool.keep_alive_time="5000" thread_pool.queue_enabled="true" thread_pool.queue_max_size="1000" thread_pool.rejection_policy="discard" oob_thread_pool.enabled="true" oob_thread_pool.min_threads="1" oob_thread_pool.max_threads="8" oob_thread_pool.keep_alive_time="5000" oob_thread_pool.queue_enabled="false" oob_thread_pool.queue_max_size="100" oob_thread_pool.rejection_policy="Run" /> <PING timeout="2000" num_initial_members="3" /> <MERGE2 max_interval="30000" min_interval="10000" /> <FD_SOCK /> <FD timeout="10000" max_tries="5" shun="true" /> <VERIFY_SUSPECT timeout="1500" /> <BARRIER /> <pbcast.NAKACK use_stats_for_retransmission="false" exponential_backoff="150" use_mcast_xmit="true" gc_lag="0" retransmit_timeout="50,300,600,1200" discard_delivered_msgs="true" /> <UNICAST timeout="300,600,1200" /> <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000" max_bytes="1000000" /> <VIEW_SYNC avg_send_interval="60000" /> <pbcast.GMS print_local_addr="true" join_timeout="3000" shun="false" view_bundling="true" /> <FC max_credits="500000" min_threshold="0.20" /> <FRAG2 frag_size="60000" /> <!--pbcast.STREAMING_STATE_TRANSFER /--> <pbcast.STATE_TRANSFER /> <!-- pbcast.FLUSH /--> </config> </stack> </protocol_stacks>
Table 23.1. Fqn type and node type in different databases
DataBase name | Node data type | FQN data type |
---|---|---|
default | BLOB | VARCHAR(512) |
HSSQL | OBJECT | VARCHAR(512) |
MySQL | LONGBLOB | VARCHAR(512) |
ORACLE | BLOB | VARCHAR2(512) |
PostgreSQL | bytea | VARCHAR(512) |
MSSQL | VARBINARY(MAX) | VARCHAR(512) |
DB2 | BLOB | VARCHAR(512) |
Sybase | IMAGE | VARCHAR(512) |
Ingres | long byte | VARCHAR(512) |