glassfish_具有GlassFish和一致性的高性能JPA –第3部分

glassfish

在我的四部分系列的第三部分中,我将说明将Coherence与EclipseLink和GlassFish结合使用的第二种策略。 这就是通过EclipseLink使用Coherence作为二级缓存(L2)的全部内容。

一般的做法

这种方法将Coherence数据网格应用于依赖于数据库托管数据的JPA应用程序,这些数据无法完全预加载到Coherence缓存中。 它可能无法预加载的一些原因包括:超出Coherence筛选器功能集的极其复杂的查询,创建陈旧缓存的第三方数据库更新,依赖于本机SQL查询,存储过程或触发器等。 这不仅是本地L2高速缓存的选项,而且在不同节点上具有其他已配置的Coherence实例,您还将获得群集范围的JPA L2高速缓存。

细节

与许多缓存一样,这是一个只读的优化。 主键查询尝试首先从Coherence获取实体,如果不成功,将查询数据库,并用查询结果更新Coherence。 针对数据库执行非主键查询,并针对Coherence检查结果,以避免缓存实体的对象构建成本。 新查询的实体将放入Coherence。 写入操作将更新数据库,如果成功提交,则将更新后的实体放入Coherence。 这种方法在Coherence文档中称为“网格缓存”。

付诸实践

如果您还没有这样做,请从上一篇博客文章开始,并准备您的环境 。 只有一件事,您需要进行更改。 对于这种情况,请返回GlassFish 3.0.1 / EclipseLink 2.0.1,因为CacheKey.getKey()方法存在问题。 2.0.1返回一个Vector ,而2.2.0返回一个Object 。 看到新的Oracle GlassFish Server 3.1支持ActiveCache,我希望此问题将在3.7 Coherence版本中得到修复。 但是直到那之前,您必须坚持使用旧的GF或EclipseLink。

无论如何,让我们使用您喜欢的IDE(例如GridCacheExample)创建一个新的Web项目。 添加所需的库(coherence.jar,toplink-grid.jar和eclipselink.jar)。 现在,让我们创建我们的实体类,并向其添加额外的@CacheInterceptor批注:

...

import oracle.eclipselink.coherence.integrated.cache.CoherenceInterceptor;
import org.eclipse.persistence.annotations.CacheInterceptor;

...

@Entity
@CacheInterceptor(value = CoherenceInterceptor.class)
public class Employee implements Serializable {

...

}

不要忘记添加@GeneratedValue(strategy = GenerationType.SEQUENCE),因为这与上一个示例相反。 完成此操作后,您必须将一致性配置添加到WEB-INF / classes文件夹。 您可以从教程开始( 示例2 )。 (请注意,其中有一个错字…重复的</ backing-map-scheme>标记)。 像配置普通的基于JPA的应用程序一样,配置persistence.xml。

<persistence-unit name="GridCacheExamplePU" transaction-type="JTA">

<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<jta-data-source>jdbc/coherence</jta-data-source>

<properties>
<property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
<property name="eclipselink.logging.level" value="FINE" />
</properties>

</persistence-unit>

基本上就是这样。 现在,您可以测试新的L2缓存。 一个简单的servlet应该可以解决问题:

public class InsertServletPart3 extends HttpServlet {

@PersistenceUnit(unitName = "GridCacheExamplePU")
EntityManagerFactory emf;

@Resource
UserTransaction tx;

...

EntityManager em = emf.createEntityManager();

tx.begin();

// some loop magic
Employee employee = new Employee();

employee.setFirstName("Markus");
employee.setLastName("Eisele");

em.persist(employee);

// some loop magic end
tx.commit();

em.close();

如果您查看日志,则可以看到以下内容:

FEIN: INSERT INTO EMPLOYEE (LASTNAME, FIRSTNAME) VALUES (?, ?)
 bind => [Eisele, Markus]
...
FEIN: Coherence(Employee)::Put: 1 value: net.eisele.coherence.entities.Employee[ id=1 ]
...

基本上,这告诉您,实际的数据库插入是由您惯常的EclipseLink执行的。 之后,您会看到Employee对象以PK为键放置到名为Employee的Coherence Cache中。

如果现在对数据库发出查询

em.createQuery("select e from Employee e where e.lastName = :lastName").setParameter("lastName", "Eisele").getResultList();

您会看到以下内容:

FEIN: SELECT ID, LASTNAME, FIRSTNAME FROM EMPLOYEE WHERE (LASTNAME = ?)
 bind => [Eisele]
FEIN: Coherence(Employee)::Get: 1 result: net.eisele.coherence.entities.Employee[ id=1 ]
FEIN: Coherence(Employee)::Put: 1 value: net.eisele.coherence.entities.Employee[ id=1 ]
...

这告诉您,查询本身是针对数据库发出的,但结果针对Coherence进行了检查,以避免已经为缓存的实体构造对象。 新查询的实体将放入Coherence。 如果发出简单的PK查询:

em.find(Employee.class, 1);

输出更改为:

FEIN: Coherence(Employee)::Get: 1 result: net.eisele.coherence.entities.Employee[ id=1 ]

而且您根本看不到任何数据库查询。 就是这样:)您的缓存有效! 谢谢阅读。 敬请期待下一部分!

进一步阅读

参考: 具有GlassFish和一致性的高性能JPA –我们的JCG合作伙伴 Markus Eisele“使用Java进行企业软件开发”博客上的 第3部分

相关文章 :

翻译自: https://www.javacodegeeks.com/2011/11/in-this-third-part-of-my-four-part.html

glassfish

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值