利用Infinispan數據網格的功能最大化Hibernate性能。 一個GWT , Spring , JPA , Hibernate , Infinispan集成教程。
在本教程中,我們將討論如何將Infinispan用作Hibernate二級緩存提供程序。 Infinispan是JBoss緩存的繼承者,也是公司在開源數據網格領域的旗艦。 為了使事情變得更有趣,我們將從上一篇關于Spring GWT Hibernate和JPA集成的文章的 結尾處繼續。 我們將使用我們的GWTSpring項目 ,并使用數據網格功能對其進行授權!
Hiberante從版本3.5開始就支持Infinispan作為二級緩存提供程序,我們將使用Hibernate 3.5.2版本和Infinispan 4.0.0版本。 您可以在此處下載Infinispan二進制發行版
強烈建議將Hibernate配置為使用JTA事務,以便Hibernate和Infinispan在同一事務中合作。 否則,對數據庫和二級緩存的操作將不會被視為單個工作單元。 這里的風險包括無法更新第二級高速緩存,而在數據庫正確提交數據的同時,舊高速緩存將保留陳舊數據。
由于我們將Web應用程序部署到一個獨立的環境( Apache – Tomcat )中,而不是為了完全滿足上述要求而部署到一個完全的,啟用JTA的應用程序服務器中,因此我們將在Spring中實現JTA環境。框架。 為此,我們需要一個符合JTA的交易管理器,而我們的首選客戶是Atomikos 。 當然,您可以使用您喜歡的任何符合JTA的事務管理器。 我們將使用Atomikos Transactions Essentials版本3.6.5,您可以從此處下載
最后但并非最不重要的一點是,我們將需要MySQL Connector / J連接到MySQL數據庫進行測試。 Atomikos Transactions Essentials的3.6.5版本已經過測試,可與MySQL Connector / J版本5.1.5很好地兼容,您可以從此處下載
為了在運行時正確集成Infinispan和Hibernate ,我們必須為Web應用程序提供所有必需的庫。 因此,復制下面在/ war / WEB-INF / lib下列出的文件(如果使用的是不同版本,請復制相關文件)
從Infinispan二進制分發
- infinispan-core.jar
- /lib/jboss-common-core-2.2.14.GA.jar
- /lib/jcip-annotations-1.0.jar
- /lib/jgroups-2.9.0.GA.jar
- /lib/marshalling-api-1.2.0.GA.jar
- /lib/rhq-pluginAnnotations-1.4.0.B01.jar
- /lib/river-1.2.0.GA.jar
從Atomikos Transactions Essentials發行
- /dist/transactions-essentials-all.jar
- /lib/jca.jar
- /lib/jms.jar
- /lib/jmx.jar
MySQL Connector / J
- mysql-connector-java-5.1.5-bin.jar
最后,為了使Atomikos在運行時正常運行,必須在我們的Web應用程序的類路徑上找到一個“ jta.properties”文件。 創建一個名為“ jta.properties”的文本文件,將其放在Eclipse項目的/ resources包下,并使用以下所示的屬性進行填充:
com.atomikos.icatch.service=com.atomikos.icatch.standalone.UserTransactionServiceFactory
com.atomikos.icatch.force_shutdown_on_vm_exit = true
com.atomikos.icatch.automatic_resource_registration = false
com.atomikos.icatch.console_log_level = INFO
現在,我們必須注意Eclipse項目的依賴性。 以下jar應包含在項目的Java構建路徑中:
- hibernate3.jar
下一步是將Hibernate配置為使用MySQL語言和二級緩存。 在/ resources / META-INF文件夾下找到persistence.xml文件,然后執行以下描述的更改:
要使用MySQL語言,請添加以下屬性:
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
要配置事務管理器以使用,請添加以下屬性:
<property name="hibernate.transaction.manager_lookup_class" value="com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup" />
要啟用啟用了查詢結果緩存的Hibernate二級緩存,您應該添加以下屬性:
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
在這一點上,我們必須指出,啟用查詢結果緩存可能不會提高性能,尤其是在您的應用程序執行主要返回唯一結果的查詢的情況下。
要配置Infinispan緩存區域工廠,請添加以下屬性:
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.infinispan.InfinispanRegionFactory"/>
我們還可以通過添加以下屬性來配置驅逐策略(此處為最近最少使用– LRU):
<property name="hibernate.cache.infinispan.entity.eviction.strategy" value= "LRU"/>
<property name="hibernate.cache.infinispan.entity.eviction.wake_up_interval" value= "2000"/>
<property name="hibernate.cache.infinispan.entity.eviction.max_entries" value= "5000"/>
<property name="hibernate.cache.infinispan.entity.expiration.lifespan" value= "60000"/>
<property name="hibernate.cache.infinispan.entity.expiration.max_idle" value= "30000"/>
通過使用逐出策略,我們可以通過無條件緩存對象來防止二級緩存占用所有可用的內存堆。 最近最少使用驅逐策略根據條目的使用頻率逐出。 在我們的情況下,將應用以下規則:
- “ wake_up_interval”屬性定義控制器進程掃描二級緩存以查找候選逐出條目的頻率(此處為每2秒一次)
- “ max_entries”屬性定義高速緩存條目的最大數量
- “壽命”屬性定義了對象可以在緩存中保留的最長時間。 如果達到了對象的使用壽命,則無論訪問頻率如何(此處為1分鐘),都將逐出該對象。
- “ max_idle”屬性定義在驅逐對象(此處為30秒)之前,對象可以空閑(不訪問)的最長時間。
最后,我們必須將“持久性單元”“事務類型”屬性更改為JTA
完整的persistence.xml文件應類似于以下提供的文件:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0"><persistence-unit name="MyPersistenceUnit" transaction-type="JTA"><provider>org.hibernate.ejb.HibernatePersistence</provider><properties><property name="hibernate.hbm2ddl.auto" value="update" /><property name="hibernate.show_sql" value="false" /><property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" /><property name="hibernate.transaction.manager_lookup_class" value="com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup" /><property name="hibernate.cache.use_second_level_cache" value="true"/><property name="hibernate.cache.use_query_cache" value="true"/><property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.infinispan.InfinispanRegionFactory"/><!-- <property name="hibernate.cache.infinispan.entity.eviction.strategy" value= "LRU"/><property name="hibernate.cache.infinispan.entity.eviction.wake_up_interval" value= "2000"/><property name="hibernate.cache.infinispan.entity.eviction.max_entries" value= "5000"/><property name="hibernate.cache.infinispan.entity.expiration.lifespan" value= "60000"/><property name="hibernate.cache.infinispan.entity.expiration.max_idle" value= "30000"/>--></properties></persistence-unit></persistence>
下一步是配置有關JTA數據源, Atomikos事務管理器和JPA / Hibernate的 Spring 。 在/ war / WEB-INF /下找到您的applicationContext.xml文件,并進行如下更改:
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:task="http://www.springframework.org/schema/task"xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"><context:component-scan base-package="com.javacodegeeks.gwtspring" /><task:annotation-driven executor="myExecutor"scheduler="myScheduler" /><task:executor id="myExecutor" pool-size="5" /><task:scheduler id="myScheduler" pool-size="10" /><tx:annotation-driven /><bean id="entityManagerFactory"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><property name="dataSource" ref="dataSource" /><property name="jpaVendorAdapter"><bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /></property></bean><bean id="dataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean"init-method="init" destroy-method="close"><property name="uniqueResourceName" value="javacodegeeks" /><property name="xaDataSourceClassName"value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /><property name="xaProperties"><props><prop key="URL">jdbc:mysql://localhost:3306/javacodegeeks</prop><prop key="user">***</prop><prop key="password">***</prop></props></property><property name="maxPoolSize" value="50" /><property name="minPoolSize" value="20" /></bean><bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"init-method="init" destroy-method="close"><property name="forceShutdown" value="false" /></bean><bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.J2eeUserTransaction"><property name="transactionTimeout" value="300" /></bean><bean id="transactionManager"class="org.springframework.transaction.jta.JtaTransactionManager"depends-on="atomikosTransactionManager,atomikosUserTransaction"><property name="transactionManager" ref="atomikosTransactionManager" /><property name="userTransaction" ref="atomikosUserTransaction" /><property name="allowCustomIsolationLevels" value="true" /></bean></beans>
這里要注意的事情:
- Spring Entity Manager Factory保留對數據源和JPA提供程序的引用,以便為我們的DAO正確提供ORM功能
- 數據源被配置為XA資源。 如上所述,這是強制性的,以便Infinispan和數據庫參與相同的事務。 您必須根據數據庫配置更改“ xaProperties” URL,用戶和密碼屬性值。
- 我們將Spring配置為使用符合JTA的 Atomikos事務管理器。
我們快完成了!
為了使實體可緩存,我們只需要這樣注釋即可。 在/ shared / dto包下找到EmployeeDTO對象,并添加@Cache批注,如下所示:
… import statements here … @Cache (usage=CacheConcurrencyStrategy.TRANSACTIONAL)
@Entity
@Table(name = "EMPLOYEE")
public class EmployeeDTO implements java.io.Serializable {private static final long serialVersionUID = 7440297955003302414L;…}
這里要注意的事情:
- 我們將“緩存并發策略”指定為“ TRANSACTIONAL”,因為我們不僅想對緩存的對象執行檢索,而且還要執行創建/更新/刪除操作。
而已! 要部署Web應用程序,只需將/ war文件夾復制到Apache – Tomact“ webapps”文件夾中。 您可以將war文件夾的名稱更改為任何您喜歡的名稱,最好在項目名稱之后將其重命名,例如GWTSpringInfinispan
在午餐之前,應用程序不要忘記創建數據庫模式,這里是“ javacodegeeks”。
午餐應用程序將您的瀏覽器指向以下地址
http:// localhost:8080 / GWTSpringInfinispan /
如果一切順利,您應該會看到您的主頁。 應該顯示兩個文本框,每個文本框后面都有一個按鈕。 在第一個文本框中,您可以將雇員保存或更新到數據庫。 作為輸入,提供ID,名稱,姓氏和職位描述,并用空格字符分隔。 單擊“ SaveOrUpdate”按鈕,將提供的信息存儲到數據庫中。 對于現有員工條目(相同的ID),將執行更新。 第二個文本框用于檢索現有員工條目。 提供員工ID,然后單擊“檢索”按鈕。 如果該員工存在,則應該看到該員工的ID,姓名,姓氏和職位描述。
Atomikos事務管理器配置為在INFO級別生成日志記錄(請參見上面的“ jta.properties”文件)。 日志文件位于Apache – Tomcat安裝的bin目錄中。 打開文件并觀察對數據庫執行的查詢。 您應該期望以下內容:
- 第一次對員工執行檢索操作。 雇員對象未緩存,并且對數據庫執行查詢。 現在應該緩存employee對象
- 對同一員工執行第二次檢索操作。 現在不應該執行任何查詢。 從Infinispan檢索數據
- 對同一員工執行更新操作。 在單個工作單元中對Infinispan和數據庫執行更新操作
- 對同一員工執行第三次查詢。 不應對數據庫執行任何查詢,并且應該看到上一步中更新的數據!
您可以從此處下載該項目(如開頭所述,并且不包含先前的文章,所需的第三方庫)
玩得開心!
賈斯汀
- GWT 2 Spring 3 JPA 2 Hibernate 3.5教程
- Spring 3 HornetQ 2.1集成教程
- Spring3 RESTful Web服務
- GWT 2 Spring 3 JPA 2 Hibernate 3.5教程– Eclipse和Maven 2展示
- 帶有Spring和Maven教程的JAX–WS
翻譯自: https://www.javacodegeeks.com/2010/06/gwt-spring-and-hibernate-enter-world-of.html