Coherence通過EntryProcessor API支持無鎖編程模型。 此功能通過減少網絡訪問并在條目上執行隱式的低級鎖定來提高系統性能。 此隱式低級鎖定功能與ConcurrentMap API提供的顯式lock(key)不同。
顯式鎖定,Transaction Framework API和Coherence資源適配器是其他作為入口處理器的Coherence事務選項。 有關Coherence交易選項的詳細信息,請參閱參考部分。 另外,對于Coherence顯式鎖定實現,可以建議使用Oracle Coherence文章中的分布式數據管理 。
可移植對象格式(POF)是獨立于平臺的序列化格式。 它允許將等效的Java,.NET和C ++對象編碼為相同的字節序列。 建議使用POF來提高系統性能,因為POF的序列化和反序列化性能要優于Standart Java序列化(根據Coherence參考文檔,在具有String,long和3個整數的簡單測試類中,(反序列化)為7比Standart Java序列化快十倍)。
Coherence提供了多種緩存類型,例如分布式(或分區),復制,樂觀,近,本地和遠程緩存。 分布式緩存定義為在任意數量的群集節點之間分布(或分區)的數據的集合,這樣,群集中的一個節點就對緩存中的每個數據負責,并且責任是分布式的(或,負載均衡)。 請注意,本文中使用了分布式緩存類型。 由于其他緩存類型不在本文范圍之內,請查看“參考”部分或“ Coherence參考”文檔。 它們的配置與分布式緩存配置非常相似。
如何通過使用覆蓋顯式鎖定的 Coherence文章分發Spring Bean –建議將Java Standart序列化比較兩個不同的實現( EntryProcessor –便攜式對象格式(POF)和顯式鎖定– Java Standart序列化 )。
在本文中,創建了一個名為OTV的新集群,并通過使用一個名為user-cache的緩存對象分發了一個spring bean。 它已分布在集群的兩個成員之間。
讓我們看一下實現AbsctractProcessor的實現, 該實現為集群中JVM之間的Spring Bean分配實現EntryProcessor接口和PortableObject接口 。
二手技術:
JDK 1.6.0_31
春天3.1.1
連貫性3.7.0 SolarisOS 5.10 Maven的3.0.2
步驟1:建立已完成的專案
創建一個Maven項目,如下所示。 (可以使用Maven或IDE插件來創建它)。

第2步:相干套餐
通過Coherence軟件包下載Coherence
步驟3:圖書館
首先,將Spring依賴項添加到Maven的pom.xml中。 請注意,Coherence庫已安裝到Local Maven Repository,并且其描述如下添加到pom.xml中。 另外,如果未使用Maven,則可以將coherence.jar文件添加到classpath。
<properties><spring.version>3.1.1.RELEASE</spring.version></properties><dependencies><!-- Spring 3 dependencies --><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><!-- Coherence library(from local repository) --><dependency><groupId>com.tangosol</groupId><artifactId>coherence</artifactId><version>3.7.0</version></dependency><!-- Log4j library --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.16</version></dependency></dependencies>
以下maven插件可用于創建runnable-jar。
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>1.3.1</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><transformers><transformerimplementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>com.otv.exe.Application</mainClass></transformer><transformerimplementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.handlers</resource></transformer><transformerimplementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.schemas</resource></transformer></transformers></configuration></execution></executions></plugin>
步驟4:建立otv-pof-config.xml
otv-pof-config.xml涵蓋了使用可移植對象格式(POF)功能進行序列化的類。 在這個例子中; User,UpdateUserProcessor和DeleteUserProcessor類實現com.tangosol.io.pof.PortableObject接口。
-Dtangosol.pof.config參數可用于在啟動腳本中定義otv-pof-config.xml路徑。
<?xml version="1.0"?>
<!DOCTYPE pof-config SYSTEM "pof-config.dtd">
<pof-config><user-type-list><!-- coherence POF user types --><include>coherence-pof-config.xml</include><!-- The definition of classes which use Portable Object Format --><user-type><type-id>1001</type-id><class-name>com.otv.user.User</class-name></user-type><user-type><type-id>1002</type-id><class-name>com.otv.user.processor.UpdateUserProcessor</class-name></user-type><user-type><type-id>1003</type-id><class-name>com.otv.user.processor.DeleteUserProcessor</class-name></user-type></user-type-list><allow-interfaces>true</allow-interfaces><allow-subclasses>true</allow-subclasses>
</pof-config>
步驟5:創建otv-coherence-cache-config.xml
otv-coherence-cache-config.xml包含(分布式或復制的)緩存方案和緩存方案映射配置。 創建的緩存配置應添加到coherence-cache-config.xml中 。
<?xml version="1.0"?><cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-configcoherence-cache-config.xsd"><caching-scheme-mapping><cache-mapping><cache-name>user-cache</cache-name><scheme-name>UserDistributedCacheWithPof</scheme-name></cache-mapping></caching-scheme-mapping><caching-schemes><distributed-scheme><scheme-name>UserDistributedCacheWithPof</scheme-name><service-name>UserDistributedCacheWithPof</service-name><serializer><instance><class-name>com.tangosol.io.pof.SafeConfigurablePofContext</class-name><init-params><init-param><param-type>String</param-type><param-value><!-- pof-config.xml path should be set-->otv-pof-config.xml</param-value></init-param></init-params></instance></serializer><backing-map-scheme><local-scheme /></backing-map-scheme><autostart>true</autostart></distributed-scheme></caching-schemes></cache-config>
步驟6:創建tangosol-coherence-override.xml
tangosol-coherence-override.xml涵蓋了集群,成員身份和可配置的緩存工廠配置。 另外,以下配置xml文件顯示了群集的第一個成員。 -Dtangosol.coherence.override參數可用于在啟動腳本中定義tangosol-coherence-override.xml路徑。
集群的第一個成員的tangosol-coherence-override.xml:
<?xml version='1.0'?><coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-operational-config coherence-operational-config.xsd"><cluster-config><member-identity><cluster-name>OTV</cluster-name><!-- Name of the first member of the cluster --><role-name>OTV1</role-name></member-identity><unicast-listener><well-known-addresses><socket-address id="1"><!-- IP Address of the first member of the cluster --><address>x.x.x.x</address><port>8089</port></socket-address><socket-address id="2"><!-- IP Address of the second member of the cluster --><address>y.y.y.y</address><port>8089</port></socket-address></well-known-addresses><!-- Name of the first member of the cluster --><machine-id>OTV1</machine-id><!-- IP Address of the first member of the cluster --><address>x.x.x.x</address><port>8089</port><port-auto-adjust>true</port-auto-adjust></unicast-listener></cluster-config><configurable-cache-factory-config><init-params><init-param><param-type>java.lang.String</param-type><param-value system-property="tangosol.coherence.cacheconfig"><!-- coherence-cache-config.xml path should be set-->otv-coherence-cache-config.xml</param-value></init-param></init-params></configurable-cache-factory-config></coherence>
集群的第二個成員的tangosol-coherence-override.xml:
<?xml version='1.0'?><coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-operational-config coherence-operational-config.xsd"><cluster-config><member-identity><cluster-name>OTV</cluster-name><!-- Name of the second member of the cluster --><role-name>OTV2</role-name></member-identity><unicast-listener> <well-known-addresses><socket-address id="1"><!-- IP Address of the first member of the cluster --><address>x.x.x.x</address><port>8089</port></socket-address><socket-address id="2"><!-- IP Address of the second member of the cluster --><address>y.y.y.y</address><port>8089</port></socket-address></well-known-addresses><!-- Name of the second member of the cluster --><machine-id>OTV2</machine-id><!-- IP Address of the second member of the cluster --><address>y.y.y.y</address><port>8089</port><port-auto-adjust>true</port-auto-adjust></unicast-listener></cluster-config><configurable-cache-factory-config><init-params><init-param><param-type>java.lang.String</param-type><param-value system-property="tangosol.coherence.cacheconfig"><!-- coherence-cache-config.xml path should be set-->otv-coherence-cache-config.xml</param-value></init-param></init-params></configurable-cache-factory-config></coherence>
步驟7:創建applicationContext.xml
applicationContext.xml已創建。
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><!-- Beans Declaration --><bean id="User" class="com.otv.user.User" scope="prototype" /><bean id="UserCacheService" class="com.otv.user.cache.srv.UserCacheService" /><bean id="CacheUpdaterTask" class="com.otv.cache.updater.task.CacheUpdaterTask"><property name="userCacheService" ref="UserCacheService" /></bean>
</beans>
步驟8:建立SystemConstants類別
SystemConstants類已創建。 此類涵蓋所有系統常數。
package com.otv.common;/*** System Constants** @author onlinetechvision.com* @since 2 Jun 2012* @version 1.0.0**/
public class SystemConstants {public static final String APPLICATION_CONTEXT_FILE_NAME = "applicationContext.xml";//Named Cache Definition...public static final String USER_CACHE = "user-cache";//Bean Names...public static final String BEAN_NAME_CACHE_UPDATER_TASK = "CacheUpdaterTask";public static final String BEAN_NAME_USER = "User";}
步驟9:創建用戶豆
創建了一個新的User Spring bean。 該bean將分布在OTV集群中的兩個節點之間。 可以實現PortableObject進行序列化。 PortableObject Interface有兩個未實現的方法,如readExternal和writeExternal 。 必須定義僅序列化的屬性。 在此示例中,所有屬性(用戶的id,名稱和姓氏)都已序列化。
package com.otv.user;import java.io.IOException;import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;/*** User Bean** @author onlinetechvision.com* @since 2 Jun 2012* @version 1.0.0**/
public class User implements PortableObject {private String id;private String name;private String surname;/*** Gets User Id** @return String id*/public String getId() {return id;}/*** Sets User Id** @param String id*/public void setId(String id) {this.id = id;}/*** Gets User Name** @return String name*/public String getName() {return name;}/*** Sets User Name** @param String name*/public void setName(String name) {this.name = name;}/*** Gets User Surname** @return String surname*/public String getSurname() {return surname;}/*** Sets User Surname** @param String surname*/public void setSurname(String surname) {this.surname = surname;}@Overridepublic String toString() {StringBuilder strBuilder = new StringBuilder();strBuilder.append("Id : ").append(id);strBuilder.append(", Name : ").append(name);strBuilder.append(", Surname : ").append(surname);return strBuilder.toString();}/*** Restore the contents of a user type instance by reading its state* using the specified PofReader object.** @param PofReader in*/public void readExternal(PofReader in) throws IOException {this.id = in.readString(0);this.name = in.readString(1);this.surname = in.readString(2);}/*** Save the contents of a POF user type instance by writing its state* using the specified PofWriter object.** @param PofWriter out*/public void writeExternal(PofWriter out) throws IOException {out.writeString(0, id);out.writeString(1, name);out.writeString(2, surname);}
}
步驟10:建立IUserCacheService接口
創建了一個新的IUserCacheService接口以執行緩存操作。
package com.otv.user.cache.srv;import com.otv.user.User;
import com.otv.user.processor.DeleteUserProcessor;
import com.otv.user.processor.UpdateUserProcessor;
import com.tangosol.net.NamedCache;/*** User Cache Service Interface** @author onlinetechvision.com* @since 2 Jun 2012* @version 1.0.0**/
public interface IUserCacheService {/*** Gets Distributed User Cache** @return NamedCache User Cache*/NamedCache getUserCache();/*** Adds user to cache** @param User user*/void addUser(User user);/*** Updates user on the cache** @param String userId* @param UpdateUserProcessor processor**/void updateUser(String userId, UpdateUserProcessor processor);/*** Deletes user from the cache** @param String userId* @param DeleteUserProcessor processor**/void deleteUser(String userId, DeleteUserProcessor processor);}
步驟11:創建UserCacheService類
通過實現IUserCacheService接口創建UserCacheService類。
package com.otv.user.cache.srv;import com.otv.cache.listener.UserMapListener;
import com.otv.common.SystemConstants;
import com.otv.user.User;
import com.otv.user.processor.DeleteUserProcessor;
import com.otv.user.processor.UpdateUserProcessor;
import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;/*** User Cache Service** @author onlinetechvision.com* @since 2 Jun 2012* @version 1.0.0**/
public class UserCacheService implements IUserCacheService {private NamedCache userCache = null; public UserCacheService() {setUserCache(CacheFactory.getCache(SystemConstants.USER_CACHE));//UserMap Listener is registered to listen user-cache operationsgetUserCache().addMapListener(new UserMapListener());} /*** Adds user to cache** @param User user*/public void addUser(User user) {getUserCache().put(user.getId(), user);}/*** Deletes user from the cache** @param String userId* @param DeleteUserProcessor processor**/public void deleteUser(String userId, DeleteUserProcessor processor) {getUserCache().invoke(userId, processor);}/*** Updates user on the cache** @param String userId* @param UpdateUserProcessor processor**/public void updateUser(String userId, UpdateUserProcessor processor) {getUserCache().invoke(userId, processor);}/*** Gets Distributed User Cache** @return NamedCache User Cache*/public NamedCache getUserCache() {return userCache;}/*** Sets User Cache** @param NamedCache userCache*/public void setUserCache(NamedCache userCache) {this.userCache = userCache;}
}
步驟12:建立USERMAPLISTENER類別
創建一個新的UserMapListener類。 該偵聽器接收分布式用戶緩存事件。
package com.otv.cache.listener;import org.apache.log4j.Logger;import com.tangosol.util.MapEvent;
import com.tangosol.util.MapListener;/*** User Map Listener** @author onlinetechvision.com* @since 2 Jun 2012* @version 1.0.0**/
public class UserMapListener implements MapListener {private static Logger logger = Logger.getLogger(UserMapListener.class);/*** This method is invoked when an entry is deleted from the cache...** @param MapEvent me*/public void entryDeleted(MapEvent me) {logger.debug("Deleted Key = " + me.getKey() + ", Value = " + me.getOldValue());}/*** This method is invoked when an entry is inserted to the cache...** @param MapEvent me*/public void entryInserted(MapEvent me) {logger.debug("Inserted Key = " + me.getKey() + ", Value = " + me.getNewValue());}/*** This method is invoked when an entry is updated on the cache...** @param MapEvent me*/public void entryUpdated(MapEvent me) {logger.debug("Updated Key = " + me.getKey() + ", New_Value = " + me.getNewValue() + ", Old Value = " + me.getOldValue());}
}
步驟13:創建UpdateUserProcessor類
AbstractProcessor是位于com.tangosol.util.processor包下的抽象類。 它實現EntryProcessor接口。
創建UpdateUserProcessor類以處理緩存上的用戶更新操作。 當為密鑰調用UpdateUserProcessor時 ,首先在集群中找到包含該密鑰的成員。 之后,從包含相關鍵的成員中調用UpdateUserProcessor ,并更新其值(用戶對象)。 因此,減少了網絡流量。
package com.otv.user.processor;import java.io.IOException;import org.apache.log4j.Logger;import com.otv.user.User;
import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;
import com.tangosol.util.InvocableMap.Entry;
import com.tangosol.util.processor.AbstractProcessor;/*** Update User Processor** @author onlinetechvision.com* @since 2 Jun 2012* @version 1.0.0**/
public class UpdateUserProcessor extends AbstractProcessor implements PortableObject { private static Logger logger = Logger.getLogger(UpdateUserProcessor.class);private User newUser;/*** This empty constructor is added for Portable Object Format(POF).**/public UpdateUserProcessor() {}public UpdateUserProcessor(User newUser) {this.newUser = newUser;}/*** Processes a Map.Entry object.** @param Entry entry* @return Object newUser*/public Object process(Entry entry) {Object newValue = null;try {newValue = getNewUser();entry.setValue(newValue);} catch (Exception e) {logger.error("Error occured when entry was being processed!", e);}return newValue;}/*** Gets new user** @return User newUser*/public User getNewUser() {return newUser;}/*** Sets new user** @param User newUser*/public void setNewUser(User newUser) {this.newUser = newUser;}/*** Restore the contents of a user type instance by reading its state* using the specified PofReader object.** @param PofReader in*/public void readExternal(PofReader in) throws IOException {setNewUser((User) in.readObject(0));}/*** Save the contents of a POF user type instance by writing its state* using the specified PofWriter object.** @param PofWriter out*/public void writeExternal(PofWriter out) throws IOException {out.writeObject(0, getNewUser());}
}
步驟14:創建DeleteUserProcessor類別
創建DeleteUserProcessor類以處理緩存上的用戶刪除操作。 當為密鑰調用DeleteUserProcessor時 ,首先在集群中找到包含該密鑰的成員。 然后,從包含相關密鑰的成員中調用DeleteUserProcessor 。 因此,減少了網絡流量。
package com.otv.user.processor;import java.io.IOException;import org.apache.log4j.Logger;import com.otv.user.User;
import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;
import com.tangosol.util.InvocableMap.Entry;
import com.tangosol.util.processor.AbstractProcessor;/*** Delete User Processor** @author onlinetechvision.com* @since 2 Jun 2012* @version 1.0.0**/
public class DeleteUserProcessor extends AbstractProcessor implements PortableObject { private static Logger logger = Logger.getLogger(DeleteUserProcessor.class);/*** Processes a Map.Entry object.** @param Entry entry* @return Object user*/public Object process(Entry entry) {User user = null;try {user = (User) entry.getValue();entry.remove(true);} catch (Exception e) {logger.error("Error occured when entry was being processed!", e);}return user;}/*** Restore the contents of a user type instance by reading its state* using the specified PofReader object.** @param PofReader in*/public void readExternal(PofReader in) throws IOException {}/*** Save the contents of a POF user type instance by writing its state* using the specified PofWriter object.** @param PofWriter out*/public void writeExternal(PofWriter out) throws IOException {}
}
步驟15:創建CacheUpdaterTask類別
創建CacheUpdaterTask類以執行緩存操作(添加,更新和刪除)并監視緩存內容。
package com.otv.cache.updater.task;import java.util.Collection;import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;import com.otv.common.SystemConstants;
import com.otv.user.User;
import com.otv.user.cache.srv.IUserCacheService;
import com.otv.user.processor.DeleteUserProcessor;
import com.otv.user.processor.UpdateUserProcessor;/*** Cache Updater Task** @author onlinetechvision.com* @since 2 Jun 2012* @version 1.0.0**/
public class CacheUpdaterTask implements BeanFactoryAware, Runnable {private static Logger log = Logger.getLogger(CacheUpdaterTask.class);private IUserCacheService userCacheService;private BeanFactory beanFactory;public void run() {try {while(true) {/*** Before the project is built for the first member,* this code block should be used instead of* method processRequestsOnSecondMemberOfCluster.*/processRequestsOnFirstMemberOfCluster();/*** Before the project is built for the second member,* this code block should be used instead of* method processRequestsOnFirstMemberOfCluster.*/
// processRequestsOnSecondMemberOfCluster();}} catch (InterruptedException e) {e.printStackTrace();}}/*** Processes the cache requests on the first member of cluster...** @throws InterruptedException*/private void processRequestsOnFirstMemberOfCluster() throws InterruptedException {//Entry is added to cache...getUserCacheService().addUser(getUser("1", "Bruce", "Willis"));//Cache Entries are being printed...printCacheEntries();Thread.sleep(10000);User newUser = getUser("1", "Client", "Eastwood");//Existent Entry is updated on the cache...getUserCacheService().updateUser(newUser.getId(), new UpdateUserProcessor(newUser));//Cache Entries are being printed...printCacheEntries();Thread.sleep(10000);//Entry is deleted from cache...getUserCacheService().deleteUser(newUser.getId(), new DeleteUserProcessor());//Cache Entries are being printed...printCacheEntries();Thread.sleep(10000);}/*** Processes the cache requests on the second member of cluster...** @throws InterruptedException*/private void processRequestsOnSecondMemberOfCluster() throws InterruptedException {//Entry is added to cache...getUserCacheService().addUser(getUser("2", "Nathalie", "Portman"));Thread.sleep(15000);User newUser = getUser("2", "Sharon", "Stone");//Existent Entry is updated on the cache...getUserCacheService().updateUser(newUser.getId(), new UpdateUserProcessor(newUser));User newUser2 = getUser("1", "Maria", "Sharapova");//Existent Entry is updated on the cache...getUserCacheService().updateUser(newUser2.getId(), new UpdateUserProcessor(newUser2));Thread.sleep(15000);//Entry is deleted from cache...getUserCacheService().deleteUser(newUser.getId(), new DeleteUserProcessor());Thread.sleep(15000);}/*** Prints cache entries**/private void printCacheEntries() {Collection<User> userCollection = (Collection<User>)getUserCacheService().getUserCache().values();for(User user : userCollection) {log.debug("Cache Content : "+user);}}/*** Gets new user instance** @param String user id* @param String user name* @param String user surname* @return User user*/private User getUser(String id, String name, String surname) {User user = getNewUserInstance();user.setId(id);user.setName(name);user.setSurname(surname);return user;}/*** Gets user cache service...** @return IUserCacheService userCacheService*/public IUserCacheService getUserCacheService() {return userCacheService;}/*** Sets user cache service...** @param IUserCacheService userCacheService*/public void setUserCacheService(IUserCacheService userCacheService) {this.userCacheService = userCacheService;}/*** Gets a new instance of User Bean** @return User*/public User getNewUserInstance() {return (User) getBeanFactory().getBean(SystemConstants.BEAN_NAME_USER);}/*** Gets bean factory** @return BeanFactory*/public BeanFactory getBeanFactory() {return beanFactory;}/*** Sets bean factory** @param BeanFactory beanFactory* @throws BeansException*/public void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}
}
步驟16:創建應用程序類
創建應用程序類以運行應用程序。
package com.otv.exe;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import com.otv.cache.updater.task.CacheUpdaterTask;
import com.otv.common.SystemConstants;/*** Application Class** @author onlinetechvision.com* @since 2 Jun 2012* @version 1.0.0**/
public class Application {/*** Starts the application** @param String[] args**/public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext(SystemConstants.APPLICATION_CONTEXT_FILE_NAME);CacheUpdaterTask cacheUpdaterTask = (CacheUpdaterTask) context.getBean(SystemConstants.BEAN_NAME_CACHE_UPDATER_TASK);Thread cacheUpdater = new Thread(cacheUpdaterTask);cacheUpdater.start();}
}
步驟17:建立專案
在構建OTV_Spring_Coherence_With_Processor_and_POF項目之后,將創建OTV_Spring_Coherence-0.0.1-SNAPSHOT.jar 。
請注意,集群成員的Coherence配置不同,因此應為每個成員分別構建項目。
步驟18:在集群的第一個成員上運行項目
在集群成員上運行了已創建的OTV_Spring_Coherence-0.0.1-SNAPSHOT.jar文件后,以下輸出日志將顯示在第一個成員的控制臺上:
--After A new cluster is created and First Member joins the cluster, a new entry is added to the cache.
02.06.2012 14:21:45 DEBUG (UserMapListener.java:33) - Inserted Key = 1, Value = Id : 1, Name : Bruce, Surname : Willis
02.06.2012 14:21:45 DEBUG (CacheUpdaterTask.java:116) - Cache Content : Id : 1, Name : Bruce, Surname : Willis
.......
--After Second Member joins the cluster, a new entry is added to the cache.
02.06.2012 14:21:45 DEBUG (UserMapListener.java:33) - Inserted Key = 2, Value = Id : 2, Name : Nathalie, Surname : Portman
.......
--Cache operations go on both first and second members of the cluster:
02.06.2012 14:21:55 DEBUG (UserMapListener.java:42) - Updated Key = 1, New_Value = Id : 1, Name : Client, Surname : Eastwood,Old Value = Id : 1, Name : Bruce, Surname : Willis02.06.2012 14:21:55 DEBUG (CacheUpdaterTask.java:116) - Cache Content : Id : 2, Name : Nathalie, Surname : Portman
02.06.2012 14:21:55 DEBUG (CacheUpdaterTask.java:116) - Cache Content : Id : 1, Name : Client, Surname : Eastwood02.06.2012 14:22:00 DEBUG (UserMapListener.java:42) - Updated Key = 2, New_Value = Id : 2, Name : Sharon, Surname : Stone,Old Value = Id : 2, Name : Nathalie, Surname : Portman02.06.2012 14:22:00 DEBUG (UserMapListener.java:42) - Updated Key = 1, New_Value = Id : 1, Name : Maria, Surname : Sharapova,Old Value = Id : 1, Name : Client, Surname : Eastwood02.06.2012 14:22:05 DEBUG (UserMapListener.java:24) - Deleted Key = 1, Value = Id : 1, Name : Maria, Surname : Sharapova
02.06.2012 14:22:05 DEBUG (CacheUpdaterTask.java:116) - Cache Content : Id : 2, Name : Sharon, Surname : Stone
02.06.2012 14:22:15 DEBUG (UserMapListener.java:24) - Deleted Key = 2, Value = Id : 2, Name : Sharon, Surname : Stone
02.06.2012 14:22:15 DEBUG (UserMapListener.java:33) - Inserted Key = 1, Value = Id : 1, Name : Bruce, Surname : Willis
02.06.2012 14:22:15 DEBUG (CacheUpdaterTask.java:116) - Cache Content : Id : 1, Name : Bruce, Surname : Willis
步驟19:下載
OTV_Spring_Coherence_With_Processor_and_POF
進一步閱讀:
連貫地執行交易
在一致性中使用可移植對象格式
Spring Framework參考3.x
參考: Online Technology Vision博客上來自JCG合作伙伴 Eren Avsarogullari的Oracle Coherence中的EntryProcessor和PortableObject特性如何分發Spring Bean 。
翻譯自: https://www.javacodegeeks.com/2012/06/distribute-spring-beans-in-oracle.html