In general, LockManager stores Lock objects, so it can give a Lock object or can release it.
Also, LockManager is responsible for removing Locks that live too long. This parameter may be configured with the "time-out" property.
JCR provides 1 basic implementation of LockManager:
org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl
In this article, we will mostly mention 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>
CacheableLockManagerImpl stores Lock objects in JBoss-cache, so Locks are replicable and affect on cluster, not only a single node. Also, JBoss-cache has JDBCCacheLoader, so Locks will be stored to the database.
Both implementations support to remove Expired Locks. LockRemover separates threads that periodically ask LockManager to remove Locks that live so long. So, the timeout for LockRemover may be set as follows (the 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 here.
clusterName ("jbosscache-cluster-name")
            must be unique.
cache.jdbc.table.name must be unique
            for each datasource.
cache.jdbc.fqn.type and
            cache.jdbc.node.type must be configured basing on your
            database.
There are a few ways to configureCacheableLockManagerImpl, and all of them configure
        JBoss-cache
        and JDBCCacheLoade.
      
See http://community.jboss.org/wiki/JBossCacheJDBCCacheLoader for more information.
Simple JbossCache configuration:
The first way is putting JbossCache configuration file path to CacheableLockManagerImpl.
This configuration is not so good as you think. As the repository may contain many workspaces, and each workspace must contain LockManager configuration, and LockManager configuration may contain the JbossCache config file. So, the total configuration will grow up. However, it is useful if you want to have a single LockManager with a special configuration.
The configuration is as follows:
<lock-manager class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.CacheableLockManagerImpl">
<properties>
<property name="time-out" value="15m" />
<property name="jbosscache-configuration" value="${gatein.conf.dir}/jcr/jbosscache/${gatein.jcr.config.type}/lock-config.xmll" />
</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="500" lockParentForChildInsertRemove="false" lockAcquisitionTimeout="20000" />
<clustering mode="replication" clusterName="JBoss-Cache-Lock-Cluster_Name">
<stateRetrieval timeout="20000" fetchInMemoryState="false" />
<sync />
</clustering>
<loaders passivation="false" shared="true">
<preload>
<node fqn="/" />
</preload>
<loader class="org.exoplatform.services.jcr.impl.core.lock.jbosscache.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">: The cluster name
            must be unique.
cache.jdbc.table.name: must be unique
            for each datasource.
cache.jdbc.node.type and
            cache.jdbc.fqn.type: must be configured
            basing on your database.
To prevent any consistency issue regarding the lock data, ensure that your cache loader is
              org.exoplatform.services.jcr.impl.core.lock.jbosscache.JDBCCacheLoader
              and your database engine is transactional.
Template JBossCache configuration
The second way is using the template JBoss-cache configuration for all LockManagers.
The 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="500" lockParentForChildInsertRemove="false" lockAcquisitionTimeout="20000" />
<clustering mode="replication" clusterName="${jbosscache-cluster-name}">
<stateRetrieval timeout="20000" fetchInMemoryState="false" />
<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.exoplatform.services.jcr.impl.core.lock.jbosscache.JDBCCacheLoader" async="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 parameters are filled by templates and will be replaced by LockManagers configuration 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="false" />
<property name="jbosscache-cluster-name" value="JCR-cluster-locks" />
<property name="jbosscache-cl-cache.jdbc.table.name" value="jcrlocks" />
<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_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" />
<property name="jbosscache-shareable" value="true" />
</properties>
</lock-manager>
Configuration requirements:
jbosscache-cl-cache.jdbc.fqn.column
            and jbosscache-cl-cache.jdbc.node.type is
            the same as cache.jdbc.fqn.type and cache.jdbc.node.type in
            JBoss-Cache configuration. You can set those data types according
            to your database type or set it as AUTO (or do not set at all) and
            data type will be detected automatically.
As you see, jgroups-configuration is moved to separate the
            configuration file - udp-mux.xml. In this case, the udp-mux.xml 
            file is a common JGroup configuration for all components
            (QueryHandler, Cache, LockManager), but you can still create your
            own configuration.
our udp-mux.xml
<config>
<UDP
singleton_name="JCR-cluster"
mcast_addr="${jgroups.udp.mcast_addr:228.10.10.10}"
mcast_port="${jgroups.udp.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="${jgroups.udp.ip_ttl:2}"
enable_bundling="false"
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>