小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

用xmemcache作為JPA(Hibernate實(shí)現(xiàn))二級(jí)緩存

 Tom.Lin 2013-04-11

1.  持久層的緩存

Hibernate中提供了兩級(jí)Cache,第一級(jí)別的緩存是Session級(jí)別的緩存,它是屬于事務(wù)范圍的緩存。這一級(jí)別的緩存由hibernate自身進(jìn)行管理的,一般情況下無(wú)需進(jìn)行干預(yù),默認(rèn)一級(jí)緩存也是打開(kāi)的;第二級(jí)別的緩存是SessionFactory級(jí)別的緩存,它是屬于進(jìn)程范圍或群集范圍的緩存。這一級(jí)別的緩存比較重量級(jí),可以進(jìn)行配置和更改,并且可以動(dòng)態(tài)加載和卸載。 Hibernate還為查詢(xún)結(jié)果提供了一個(gè)查詢(xún)緩存,它依賴(lài)于第二級(jí)緩存。

每個(gè)事務(wù)都有單獨(dú)的第一級(jí)緩存進(jìn)程范圍或集群范圍,緩存被同一個(gè)進(jìn)程或集群范圍內(nèi)的所有事務(wù)共享并發(fā)訪(fǎng)問(wèn)策略。由于每個(gè)事務(wù)都擁有單獨(dú)的第一級(jí)緩存,因此一級(jí)緩存不會(huì)出現(xiàn)并發(fā)問(wèn)題,無(wú)需提供并發(fā)訪(fǎng)問(wèn)策略,由于多個(gè)事務(wù)會(huì)同時(shí)訪(fǎng)問(wèn)第二級(jí)緩存中相同數(shù)據(jù),因此二級(jí)緩存必須提供適當(dāng)?shù)牟l(fā)訪(fǎng)問(wèn)策略,來(lái)保證特定的事務(wù)隔離級(jí)別數(shù)據(jù)過(guò)期策略沒(méi)有提供數(shù)據(jù)過(guò)期策略。處于一級(jí)緩存中的對(duì)象永遠(yuǎn)不會(huì)過(guò)期,除非應(yīng)用程序顯式清空緩存或者清除特定的對(duì)象必須提供數(shù)據(jù)過(guò)期策略,如基于內(nèi)存的緩存中的對(duì)象的最大數(shù)目,允許對(duì)象處于緩存中的最長(zhǎng)時(shí)間,以及允許對(duì)象處于緩存中的最長(zhǎng)空閑時(shí)間物理存儲(chǔ)介質(zhì)內(nèi)存內(nèi)存和硬盤(pán)。

對(duì)象的散裝數(shù)據(jù)首先存放在基于內(nèi)存的緩存中,當(dāng)內(nèi)存中對(duì)象的數(shù)目達(dá)到數(shù)據(jù)過(guò)期策略中指定上限時(shí),就會(huì)把其余的對(duì)象寫(xiě)入基于硬盤(pán)的緩存中。緩存的軟件實(shí)現(xiàn)是在HibernateSession的實(shí)現(xiàn)中包含了緩存的實(shí)現(xiàn)由第三方提供,Hibernate僅提供了緩存適配器(CacheProvider),用于把特定的緩存插件集成到Hibernate中。啟用緩存的方式只要應(yīng)用程序通過(guò)Session接口來(lái)執(zhí)行保存、更新、刪除、加載和查詢(xún)數(shù)據(jù)庫(kù)數(shù)據(jù)的操作,Hibernate就會(huì)啟用第一級(jí)緩存,把數(shù)據(jù)庫(kù)中的數(shù)據(jù)以對(duì)象的形式拷貝到緩存中,對(duì)于批量更新和批量刪除操作,如果不希望啟用第一級(jí)緩存,可以繞過(guò)Hibernate API,直接通過(guò)JDBC API來(lái)執(zhí)行操作。用戶(hù)可以在單個(gè)類(lèi)或類(lèi)集合的粒度上配置第二級(jí)緩存。如果類(lèi)的實(shí)例被經(jīng)常讀但很少被修改,例如常量數(shù)據(jù)集合,就可以考慮使用第二級(jí)緩存。

只有為某個(gè)類(lèi)或集合配置了第二級(jí)緩存,Hibernate在運(yùn)行時(shí)才會(huì)把它的實(shí)例加入到第二級(jí)緩存中。用戶(hù)管理緩存的方式第一級(jí)緩存的物理介質(zhì)為內(nèi)存,內(nèi)存雖然存取速度比較快,奈何由于內(nèi)存容量有限,必須通過(guò)恰當(dāng)?shù)臋z索策略和檢索方式來(lái)限制加載對(duì)象的數(shù)目。Session evit()方法可以顯式清空緩存中特定對(duì)象,但這種方法不值得推薦。第二級(jí)緩存的物理介質(zhì)可以是內(nèi)存和硬盤(pán),因此第二級(jí)緩存可以存放大量的數(shù)據(jù),數(shù)據(jù)過(guò)期策略的maxElementsInMemory屬性值可以控制內(nèi)存中的對(duì)象數(shù)目。管理第二級(jí)緩存主要包括兩個(gè)方面:選擇需要使用第二級(jí)緩存的持久類(lèi),設(shè)置合適的并發(fā)訪(fǎng)問(wèn)策略:選擇緩存適配器,設(shè)置合適的數(shù)據(jù)過(guò)期策略。

對(duì)應(yīng)于一級(jí)緩存,當(dāng)應(yīng)用程序調(diào)用Sessionsave()、update()savaeOrUpdate()、get()load(),以及調(diào)用查詢(xún)接口的list()、iterate()filter()方法時(shí),如果在Session緩存中還不存在相應(yīng)的對(duì)象,Hibernate就會(huì)把該對(duì)象加入到第一級(jí)緩存中。當(dāng)清理緩存時(shí),Hibernate會(huì)根據(jù)緩存中對(duì)象的狀態(tài)變化來(lái)同步更新數(shù)據(jù)庫(kù)。Session為應(yīng)用程序提供了兩個(gè)管理緩存的方法:evict(Object obj):從緩存中清除參數(shù)指定的持久化對(duì)象。 clear():清空緩存中所有持久化對(duì)象。

Hibernate二級(jí)緩存策略的一般過(guò)程如下:
1)
條件查詢(xún)的時(shí)候,總是發(fā)出一條select語(yǔ)句(選擇所有字段)這樣的SQL語(yǔ)句查詢(xún)數(shù)據(jù)庫(kù),一次獲得所有的數(shù)據(jù)對(duì)象。

2) 把獲得的所有數(shù)據(jù)對(duì)象根據(jù)ID放入到第二級(jí)緩存中。

3) 當(dāng)Hibernate根據(jù)ID訪(fǎng)問(wèn)數(shù)據(jù)對(duì)象的時(shí)候,首先從Session一級(jí)緩存中查;查不到,如果配置了二級(jí)緩存,那么從二級(jí)緩存中查;查不到,再查詢(xún)數(shù)據(jù)庫(kù),把結(jié)果按照ID放入到緩存。

4) 刪除、更新、增加數(shù)據(jù)的時(shí)候,同時(shí)更新緩存。

Hibernate二級(jí)緩存策略,是針對(duì)于ID(主鍵)查詢(xún)的緩存策略,對(duì)于條件查詢(xún)則毫無(wú)作用。為此,Hibernate提供了針對(duì)條件查詢(xún)的Query Cache,就是之前說(shuō)的查詢(xún)緩存。更新緩存的代價(jià)比從緩存中查詢(xún)的代價(jià)大得多,因?yàn)榫彺娴讓邮莻€(gè)大Map或者是個(gè)大Item(org.hibernate.cache.ReadWriteCache.Item)進(jìn)行存儲(chǔ)的。而且存儲(chǔ)的一般都是對(duì)象,空間移動(dòng),存取,修改的代價(jià)可想而知。那么什么樣的數(shù)據(jù)適合存放到第二級(jí)緩存中?

1) 很少被修改的數(shù)據(jù)

2) 不是很重要的數(shù)據(jù),允許出現(xiàn)偶爾并發(fā)的數(shù)據(jù)

3) 不會(huì)被高并發(fā)訪(fǎng)問(wèn)的數(shù)據(jù)

4) 參考數(shù)據(jù),指的是供應(yīng)用參考的常量數(shù)據(jù),它的實(shí)例數(shù)目有限,它的實(shí)例會(huì)被許多其他類(lèi)的實(shí)例引用,實(shí)例極少或者從來(lái)不會(huì)被修改。

那么什么樣的數(shù)據(jù)不適合存放到第二級(jí)緩存中?

1) 經(jīng)常被修改的數(shù)據(jù),代價(jià)太大了,得不償失。

2) 金錢(qián)敏感數(shù)據(jù),絕對(duì)不允許出現(xiàn)并發(fā)

3) 與其他應(yīng)用共享的數(shù)據(jù)。

Hibernate的二級(jí)緩存往往要借助第三方的工具,下面是幾種常用的緩存工具:

1):EhCache:可作為進(jìn)程范圍的緩存,存放數(shù)據(jù)的物理介質(zhì)可以是內(nèi)存或硬盤(pán),對(duì)Hibernate的查詢(xún)緩存提供了支持。

2):OSCache:可作為進(jìn)程范圍的緩存,存放數(shù)據(jù)的物理介質(zhì)可以是內(nèi)存或硬盤(pán),提供了豐富的緩存數(shù)據(jù)過(guò)期策略,對(duì)Hibernate的查詢(xún)緩存提供了支持。

3):SwarmCache:可作為群集范圍內(nèi)的緩存,但不支持Hibernate的查詢(xún)緩存。

4):JBossCache:可作為群集范圍內(nèi)的緩存,支持事務(wù)型并發(fā)訪(fǎng)問(wèn)策略,對(duì)Hibernate的查詢(xún)緩存提供了支持。

5):當(dāng)然了還有我們這次要介紹的Memcacahe

Memcacahe這個(gè)開(kāi)源項(xiàng)目,是一個(gè)高性能的分布式的內(nèi)存對(duì)象緩存系統(tǒng),通過(guò)在內(nèi)存里維護(hù)一個(gè)統(tǒng)一的巨大的Hash表,能夠用來(lái)存儲(chǔ)各種格式的數(shù)據(jù)。其實(shí)Memcache最開(kāi)始是作為高可用集群的緩存解決方案的。一些互聯(lián)網(wǎng)的非敏感信息就放到Memcache中,用戶(hù)第一次訪(fǎng)問(wèn)還是從數(shù)據(jù)庫(kù)里面進(jìn)行查詢(xún),之后放到緩存中,之后用戶(hù)的訪(fǎng)問(wèn)都從緩存中去取。至于緩存更新,根據(jù)業(yè)務(wù)不同,有不同的方案,比如一旦數(shù)據(jù)發(fā)生變更,就是先更新數(shù)據(jù)庫(kù)后,立即更新緩存數(shù)據(jù),還有一種做法就是對(duì)于十分不敏感的數(shù)據(jù)僅僅更新緩存,定時(shí)向數(shù)據(jù)庫(kù)進(jìn)行同步和更新。它還可以作為高分布式系統(tǒng)的Session的解決方案。Memcache還可以作為Hibernate的二級(jí)緩存插件。hibernate-memcached這個(gè)java類(lèi)庫(kù)用于在Hibernate中使用Memcached作為一個(gè)二級(jí)分布式緩存。支持實(shí)體和查詢(xún)緩存。

2.  搭建環(huán)境

hibernate-memcachedGoogle的托管項(xiàng)目,開(kāi)發(fā)源代碼。

http://code.google.com/p/hibernate-memcached/可以下載

 

Memcache自身需要一個(gè)服務(wù)端,windows版本,筆者找了好久,終于在http://code./memcached/找到,讀者可自己下載。下載后是一個(gè)exe文件。

要想在我們自己的項(xiàng)目中使用好Memcache,還得使用一個(gè)Memcacahe客戶(hù)端程序。筆者極力推崇dennis兄的Xmemcached作為客戶(hù)端。可以從

http://code.google.com/p/xmemcached/下載。當(dāng)然memcache還需要依賴(lài)slf4j-api包。

之后就是JPA規(guī)范與Hibernate相關(guān)包的導(dǎo)入了,當(dāng)然可以借助IDE了,筆者前面也有相關(guān)筆記寫(xiě)到,在此就不再贅述了。搭建好環(huán)境后的工作空間如下

 3.  編寫(xiě)業(yè)務(wù)代碼

首先先配置JPA的屬性

Java代碼  收藏代碼
  1. <persistence-unit name="HibernateSecondCachePU"  
  2.     transaction-type="RESOURCE_LOCAL">  
  3.     <provider>org.hibernate.ejb.HibernatePersistence</provider>  
  4.     <class>pojo.Productsmessageinfo</class>  
  5.     <class>pojo.Products</class>  
  6.     <properties>  
  7.         <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />  
  8.         <property name="hibernate.connection.url" value="jdbc:mysql://127.0.0.1:3306/tgweb" />  
  9.         <property name="hibernate.connection.username" value="liuyan" />  
  10.         <property name="hibernate.connection.password" value="111111" />  
  11.         <property name="hibernate.hbm2ddl.auto" value="update" />  
  12.         <property name="hibernate.cache.use_second_level_cache"  
  13.             value="true" />  
  14.         <property name="hibernate.show_sql" value="true" />  
  15.         <!-- 結(jié)構(gòu)化方式存儲(chǔ) -->  
  16.         <property name="hibernate.cache.use_structured_entries"  
  17.             value="true" />  
  18.         <!-- 查詢(xún)緩存 -->  
  19.         <property name="hibernate.cache.use_query_cache" value="true" />  
  20.         <!-- 二級(jí)緩存服務(wù)類(lèi) -->  
  21.         <property name="hibernate.cache.provider_class"  
  22.             value="com.googlecode.hibernate.memcached.MemcachedCacheProvider" />  
  23.         <!-- 二級(jí)緩存服務(wù)地址和端口 -->  
  24.         <property name="hibernate.memcached.servers" value="127.0.0.1:11211" />  
  25.         <!-- memcache的調(diào)用客戶(hù)端 -->  
  26.         <property name="hibernate.memcached.memcacheClientFactory"  
  27.             value="net.rubyeye.xmemcached.utils.hibernate.XmemcachedClientFactory" />  
  28.     </properties>  
  29. </persistence-unit>  

當(dāng)著明人不說(shuō)暗話(huà),其實(shí)這段配置中,其他配置都好說(shuō),就是hibernate.cache.use_structured_entries這個(gè)配置,筆者查了半天,不是很明白。文檔說(shuō)是結(jié)構(gòu)化存儲(chǔ),沒(méi)說(shuō)怎么個(gè)結(jié)構(gòu)化存儲(chǔ)~網(wǎng)上都說(shuō)是人性化存儲(chǔ),筆者的疑問(wèn)是,什么是人性化存儲(chǔ)?怎么樣進(jìn)行人性化存儲(chǔ)?不是特別明白,這個(gè)大家可以討論。

下面咱們來(lái)看實(shí)體POJO

Java代碼  收藏代碼
  1. package pojo;  
  2.   
  3. import static javax.persistence.GenerationType.IDENTITY;  
  4.   
  5. import java.sql.Timestamp;  
  6. import javax.persistence.Column;  
  7. import javax.persistence.Entity;  
  8. import javax.persistence.FetchType;  
  9. import javax.persistence.GeneratedValue;  
  10. import javax.persistence.Id;  
  11. import javax.persistence.JoinColumn;  
  12. import javax.persistence.ManyToOne;  
  13. import javax.persistence.Table;  
  14. import org.hibernate.annotations.CacheConcurrencyStrategy;  
  15.   
  16. @Entity  
  17. @Table(name = "products", catalog = "tgweb")  
  18. @org.hibernate.annotations.Cache(usage =CacheConcurrencyStrategy.READ_WRITE)  
  19. public class Products implements java.io.Serializable {  
  20.   
  21.     // Fields  
  22.   
  23.     private Long id;  
  24.     private Productsmessageinfo productsmessageinfo;  
  25.     private Double nowPrice;  
  26.     private String picture;  
  27.     private String productMess;  
  28.     private String productName;  
  29.     private Double sourcePrice;  
  30.     private Timestamp updateTime;  
  31.     private String productsMessageInfo;  
  32.   
  33.     // Constructors  
  34.   
  35.     /** default constructor */  
  36.     public Products() {  
  37.     }  
  38.   
  39.     @Id  
  40.     @GeneratedValue(strategy = IDENTITY)  
  41.     @Column(name = "id", unique = true, nullable = false)  
  42.     public Long getId() {  
  43.         return this.id;  
  44.     }  
  45.   
  46.     public void setId(Long id) {  
  47.         this.id = id;  
  48.     }  
  49.   
  50.     @ManyToOne(fetch = FetchType.LAZY)  
  51.     @JoinColumn(name = "productsMessageInfo_ID")  
  52.     public Productsmessageinfo getProductsmessageinfo() {  
  53.         return this.productsmessageinfo;  
  54.     }  
  55.     …………………………省去setter/getter  
  56.   
  57. }  

 其中類(lèi)上的標(biāo)注,詳細(xì)解釋請(qǐng)看http://www./problems/49111它是二級(jí)緩存的讀取策略。針對(duì)不同的實(shí)體需求,配置不同的訪(fǎng)問(wèn)策略。請(qǐng)注意注解的全路徑。

DAO代碼就不全給出了,比較簡(jiǎn)單,僅僅給出片段即可

Java代碼  收藏代碼
  1. public static EntityManager getEntityManager() {  
  2.     EntityManager manager = threadLocal.get();        
  3.     if (manager == null || !manager.isOpen()) {  
  4.         manager = emf.createEntityManager();  
  5.         threadLocal.set(manager);  
  6.     }  
  7.     return manager;  
  8. }  
  9.   
  10. public Products findById(Long id) {  
  11.     try {  
  12.         Products instance = getEntityManager().find(Products.class, id);  
  13.         return instance;  
  14.     } catch (RuntimeException re) {  
  15.         throw re;  
  16.     }  
  17. }  

 4.  測(cè)試

Java代碼  收藏代碼
  1. public void test02() {  
  2.   
  3.         Products products1 = productsDAO.findById(1l);  
  4.         System.out  
  5.                 .println(products1.getId() + ":" + products1.getProductName());  
  6.         Products products2 = productsDAO.findById(1l);  
  7.         System.out  
  8.                 .println(products2.getId() + ":" + products2.getProductName());  
  9.   
  10.     }  

 我們先將Hibernate的二級(jí)緩存在配置文件中關(guān)掉。就是設(shè)為false運(yùn)行測(cè)試代碼試試。

運(yùn)行后控制臺(tái)效果如下

Java代碼  收藏代碼
  1. log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).  
  2. log4j:WARN Please initialize the log4j system properly.  
  3. 2011-6-29 16:19:37 dao.EntityManagerHelper log  
  4. 信息: finding Products instance with id: 1  
  5. Hibernate: select products0_.id as id1_0_, products0_.nowPrice as nowPrice1_0_, products0_.picture as picture1_0_, products0_.productMess as productM4_1_0_, products0_.productName as productN5_1_0_, products0_.productsMessageInfo as products6_1_0_, products0_.productsMessageInfo_ID as products9_1_0_, products0_.sourcePrice as sourcePr7_1_0_, products0_.updateTime as updateTime1_0_ from tgweb.products products0_ where products0_.id=?  
  6. 2011-6-29 16:19:37 dao.EntityManagerHelper log  
  7. 信息: finding Products instance with id: 1  
  8. 1:商品  
  9. 1:商品  

 從輸出的sql語(yǔ)句可以看到執(zhí)行后,先從數(shù)據(jù)庫(kù)查詢(xún),之后去取記錄從Hibernate的一級(jí)緩存中獲得,就不在查庫(kù)了。好的,我們?cè)俅芜\(yùn)行測(cè)試代碼,輸出的效果和第一次運(yùn)行一樣,還是要先查一道數(shù)據(jù)庫(kù),控制臺(tái)會(huì)輸出sql語(yǔ)句。

下面我們開(kāi)啟memcached服務(wù),將Hibernate的二級(jí)緩存配置打開(kāi)。運(yùn)行測(cè)試代碼,第一次運(yùn)行和沒(méi)開(kāi)啟二級(jí)緩存前效果一樣,但是第二次運(yùn)行測(cè)試代碼,效果如下

Java代碼  收藏代碼
  1. log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).  
  2. log4j:WARN Please initialize the log4j system properly.  
  3. 2011-6-29 16:31:08 dao.EntityManagerHelper log  
  4. 信息: finding Products instance with id: 1  
  5. 1:商品  
  6. 2011-6-29 16:31:08 dao.EntityManagerHelper log  
  7. 信息: finding Products instance with id: 1  
  8. 1:商品  

 此時(shí)并沒(méi)有再次訪(fǎng)問(wèn)數(shù)據(jù)庫(kù),而是直接從memcached緩存中獲取。之后數(shù)次運(yùn)行測(cè)試代碼,效果都是從緩存獲取,那么我們關(guān)閉memcached服務(wù)。再運(yùn)行測(cè)試代碼,效果如下

Java代碼  收藏代碼
  1. log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).  
  2. log4j:WARN Please initialize the log4j system properly.  
  3. 2011-6-29 16:33:25 dao.EntityManagerHelper log  
  4. 信息: finding Products instance with id: 1  
  5. Hibernate: select products0_.id as id1_0_, products0_.nowPrice as nowPrice1_0_, products0_.picture as picture1_0_, products0_.productMess as productM4_1_0_, products0_.productName as productN5_1_0_, products0_.productsMessageInfo as products6_1_0_, products0_.productsMessageInfo_ID as products9_1_0_, products0_.sourcePrice as sourcePr7_1_0_, products0_.updateTime as updateTime1_0_ from tgweb.products products0_ where products0_.id=?  
  6. 1:商品  
  7. 1:商品  
  8. 2011-6-29 16:33:26 dao.EntityManagerHelper log  
  9. 信息: finding Products instance with id: 1  

 發(fā)現(xiàn)依然和沒(méi)開(kāi)啟緩存的效果是一樣的,從數(shù)據(jù)庫(kù)去取。證明緩存生效。

而且我們還可以通過(guò)XMemcached客戶(hù)端代碼獲取緩存對(duì)象,代碼如下

Java代碼  收藏代碼
  1. package dao;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.HashMap;  
  5. import java.util.concurrent.TimeoutException;  
  6.   
  7. import net.rubyeye.xmemcached.KeyIterator;  
  8. import net.rubyeye.xmemcached.MemcachedClient;  
  9. import net.rubyeye.xmemcached.MemcachedClientBuilder;  
  10. import net.rubyeye.xmemcached.XMemcachedClientBuilder;  
  11. import net.rubyeye.xmemcached.exception.MemcachedException;  
  12. import net.rubyeye.xmemcached.utils.AddrUtil;  
  13.   
  14. import org.hibernate.cache.ReadWriteCache.Item;  
  15.   
  16. public class MemcacheClientTest {  
  17.     /** 
  18.      * @param args 
  19.      * @throws IOException 
  20.      */  
  21.     @SuppressWarnings("unchecked")  
  22.     public static void main(String[] args) throws IOException {  
  23.         MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil  
  24.                 .getAddresses("localhost:11211"));  
  25.         MemcachedClient memcachedClient = null;  
  26.         try {  
  27.             memcachedClient = builder.build();  
  28.             // 取所有key  
  29.             KeyIterator it = memcachedClient.getKeyIterator(AddrUtil  
  30.                     .getOneAddress("localhost:11211"));  
  31.             while (it.hasNext()) {  
  32.                 String key = it.next();  
  33.                 System.out.println("key------:" + key);  
  34.             }  
  35.   
  36.             Item item = memcachedClient.get("pojo.Products:0:1");  
  37.             HashMap productsHashMap = (HashMap) item.getValue();  
  38.             System.out.println("products:" + productsHashMap.get("id") + ":"+ productsHashMap.get("productName"));  
  39.         } catch (MemcachedException e) {  
  40.             System.err.println("MemcachedClient operation fail");  
  41.             e.printStackTrace();  
  42.         } catch (TimeoutException e) {  
  43.             System.err.println("MemcachedClient operation timeout");  
  44.             e.printStackTrace();  
  45.         } catch (InterruptedException e) {   
  46.             e.printStackTrace();  
  47.         } catch (IOException e) {  
  48.             e.printStackTrace();  
  49.         }  
  50.         try {  
  51.             memcachedClient.shutdown();  
  52.         } catch (IOException e) {  
  53.             System.err.println("Shutdown MemcachedClient fail");  
  54.             e.printStackTrace();  
  55.         }  
  56.     }  
  57. }  

 5.  總結(jié)

當(dāng)然,就像剛開(kāi)始說(shuō)的,Hibernate還有很多其他緩存組件可用,不過(guò)筆者認(rèn)為memcache最大的優(yōu)點(diǎn)就是達(dá)到了分布式的二級(jí)緩存。尤其是面向集群系統(tǒng),并發(fā)量又比較大,多個(gè)服務(wù)器之間公用一個(gè)緩存,減輕各個(gè)Node的負(fù)載,當(dāng)然放到二級(jí)緩存的數(shù)據(jù)并發(fā)量不能太大。讀取操作倒是可以,如果遇到更新操作會(huì)有極小的數(shù)據(jù)有效性的延遲。就是數(shù)據(jù)更新了,緩存還沒(méi)來(lái)得及更新呢,就被另一個(gè)線(xiàn)程取走了。這個(gè)時(shí)候就是無(wú)效的,當(dāng)然客戶(hù)端XMemcachedCAS進(jìn)行樂(lè)觀鎖鎖定,顯示報(bào)出異常等等措施,但是對(duì)于系統(tǒng)的運(yùn)行效率上就得犧牲一些。總得來(lái)說(shuō)現(xiàn)在使用memcache作為ORM二級(jí)緩存漸漸成為了趨勢(shì)。

 

PS:參考資料

http://developer.51cto.com/art/200909/153715.htm

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多