依赖包:
jboss-cache-1.4.1.jar
jboss-client-4.0.2.jar
jboss-common-client.jar
jboss-jmx.ja
jboss-system-4.0.2.jar
jgroups-2.4.1.jar
concurrence
check those under the attached file ensential-jars.zip
配置
references:
The manager look up classes setting:
http://hi.baidu.com/javajavajava/blog/item/beb31a3f251f52ea54e723ae.html
# to use the second-level cache with JTA, Hibernate must be able to obtain the JTA transactionManager
#hibernate.transaction.manager_lookup_class org.hibernate.transaction.JBossTransactionManagerLookup
#hibernate.transaction.manager_lookup_class org.hibernate.transaction.WeblogicTransactionManagerLookup
#hibernate.transaction.manager_lookup_class org.hibernate.transaction.WebSphereTransactionManagerLookup
#hibernate.transaction.manager_lookup_class org.hibernate.transaction.OrionTransactionManagerLookup
#hibernate.transaction.manager_lookup_class org.hibernate.transaction.ResinTransactionManagerLookup
The frequentely asked questions,
There are many basic and critical questions asked here
1. 配置 Classes/Collections
为了方便管理classes/collections二级缓存的配置, 最好的办法就是将配置统一放在一个地方. 我们可以将所有的Caching objects/collections 统一放在SessionFactory的配置位置
以Spring+Hibernate 配置为例.
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> ..... <!-- Centralize those configuration in one place for well management and tuning --> <!-- To enable the classes --> <property name="entityCacheStrategies"> <props> <prop key="Test.Country">read-only</prop> <!-- JBoss caching only support the concurrence level with read-only and transactional(REPEATABLE-READ). Using OPTIMISTIC Node Locking Strategy to enhance the performance --> <prop key="Test.Memeber">transactional</prop> </props> </property> <property name="collectionCacheStrategies"> <props> <prop key="Test.Member.addresses">transactional</prop> </props> </property> ...... </bean>
2. 启用 2nd-level cache
以 Spring+Hibernate 为列, 在hibernateProperties的配置信息里面添加如下信息
a. 如果是悲观锁的方式,定义provider_class 为 org.hibernate.cache.TreeCacheProvider
<bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="properties"> ...... <prop key="hibernate.cache.provider_class">org.hibernate.cache.TreeCacheProvider</prop> <prop key="hibernate.cache.use_second_level_cache">true</prop> <prop key="hibernate.cache.use_query_cache">true</prop> ..... </property> </bean>
b. 如果是乐观锁的方式,定义provider_class 为 org.hibernate.cache.OptimisticTreeCacheProvider,同事需要显示设定 hibernate.transaction.manager_lookup_class, 我本地的编译环境是基于WebSphere的,所以设定为 WebSphereTransactionManagerLookup
<bean id="hibernateProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="properties"> ...... <prop key="hibernate.cache.provider_class">org.hibernate.cache.OptimisticTreeCacheProvider</prop> <prop key="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereTransactionManagerLookup</prop> <prop key="hibernate.cache.use_second_level_cache">true</prop> <prop key="hibernate.cache.use_query_cache">true</prop> ..... </property> </bean>
如何设定乐观锁和悲观锁,将在后面介绍.
4. JBoss Caching 的数据同步方式
LOCAL - local, non-clustered cache. Local caches don't join a cluster and don't communicate with other caches in a cluster. Therefore their contents don't need to be Serializable; however, we recommend making them Serializable, allowing you the flexibility to change the cache mode at any time.
REPL_SYNC - synchronous replication. Replicated caches replicate all changes to the other caches in the cluster. Synchronous replication means that changes are replicated and the caller blocks until replication acknowledgements are received.
REPL_ASYNC - asynchronous replication. Similar to REPL_SYNC above, replicated caches replicate all changes to the other caches in the cluster. Being asynchronous, the caller does not block until replication acknowledgements are received.
INVALIDATION_SYNC - if a cache is configured for invalidation rather than replication, every time data is changed in a cache other caches
in the cluster receive a message informing them that their data is now stale and should be evicted from memory.
Then the cache will reload the data from datasource, This reduces replication overhead while still being able to
invalidate stale data on remote caches.
INVALIDATION_ASYNC - as above, except this invalidation mode causes invalidation messages to be broadcast asynchronously.
3. 乐观锁 和 悲观锁有何区别
乐观锁
如果设定为乐观锁的模式, 所配置的Concurrence Transactional 将会失效, 并且将忽略已设定的REPEATABLE_READ隔离级别。
乐观锁只会作用在单个JVM里面,他通过特定的Timestamp来为Entity设定一个版本来管理读取的数据.
有人会问,如果Clusters间没有设定隔离级别,是否在多个clusters间会有脏读的风险?
我的回答是如果设定同步方式为 REAL_ASYN 或者INVALIDATION_ASYN的时候会,但是几率实在太小,可以忽略不计 - 只有在两个Clusters 同时访问同一个Caching Entity的时候,这个时候,因为Repeatable-read隔离级别在clusters间失效,所以这两个Clusters可以同时访问,此时一个Cluster做了Update,但事务还没来得及提交(在事务未提交之前-Async的模式, JBoss Caching不会同步脏数据),另外一个Cluster 已经读取,这种情况下,脏读发生。 所以,在采用乐观锁的时候,如果要完全避免脏读,只能用REAL_SYNC方式来同步脏数据,避免脏读,如果有任何一个数据发生更改,当前cluster的进程等待,并且立即同步clusters间的脏数据,这样的话,就完全可以避免脏读。 但是这样做的弊端是,在多个Clusters的情况下,性能较低。
JBoss推荐使用INVALIDATION_SYNC的方式来处理脏数据,当然在使用乐观锁的时候有很小的几率下会产生脏读,而且二级缓存不应该存放关键的业务数据,所以即便是乐观锁,也应该使用INVALIDATION_SYNC的方式,性能优先.
配置的样例参考附件 treecach-optimistic.xml.zip
悲观锁
悲观锁可以支持所有的事务模式, READ-ONLY, READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ. 但是在 Clusters 间 Concurrence 的事务模式只能支持 READ-ONLY and REPEATABLE-READ,在单个JVM里面,READ-UNCOMMITTED 和 READ-COMMITTED生效. 如果你的JBOSS Caching部署在单个JVM上,设置同步方式为LOCAL,这样可以启用事务隔离级别为READ-UNCOMMITTED, READ-COMMITTED。在 Clusters的情况下设定为 REPEATABLE-READ隔离级别. 悲观锁通常会有 performance的问题,因为高并发下Caching的数据会发生频繁的锁定,Caching 数据间的死锁问题也会莫名其妙的,频繁的发生. 所以这也是 JBoss Caching 为什么推荐使用 乐观锁的原因.
配置的样例参考附件 treecach-pessmistic.xml.zip
Jboss-cache-1.4.1.jar 启动的时候,默认读取 treecache-optimistic.xml
4. JBoss 是如何 同步数据的
JBoss是通过设置JGroups,将Cluster定义为JGroups里面的成员,JGroups 会根据定义的ClusterName 给具有同组名的Group成员发送广播来同步数据. 配置片段
........... <!-- Name of cluster. Needs to be the same for all members(ATS and WAS server we have so far), in order to find each other by JGroup by the same cluster name--> <attribute name="ClusterName">SampleCluster</attribute> ........... <!-- Do not change the following attributes if not necessary, those are the default attributes to configure the JGroups. --> <attribute name="ClusterConfig"> <config> <UDP loopback="false" /><!-- If windows server, set it as true--> <PING timeout="2000" num_initial_members="3" up_thread="false" down_thread="false" /> <FD_SOCK /> <pbcast.NAKACK gc_lag="50" retransmit_timeout="600,1200,2400,4800" max_xmit_size="8192" up_thread="false" down_thread="false" /> <UNICAST timeout="600,1200,2400" window_size="100" min_threshold="10" down_thread="false" /> <pbcast.STABLE desired_avg_gossip="20000" up_thread="false" down_thread="false" /> <FRAG frag_size="8192" down_thread="false" up_thread="false" /> <pbcast.GMS join_timeout="5000" join_retry_timeout="2000" shun="true" print_local_addr="true" /> <pbcast.STATE_TRANSFER up_thread="true" down_thread="true" /> </config> </attribute> ......
测试JBoss Caching配置
http://lists.jboss.org/pipermail/jboss-user/2007-May/060666.html
in progress...