使用Infinispan进行Camel的事务性缓存

不久前,我为Camel 创建了Redis连接器。 Redis是很棒的键值存储(还有更多),但是随后我需要一个在与Camel相同的JVM中运行的缓存,并注意到Infinispan已切换到ASL v2 。 Camel中已经有其他用于在JVM上进行缓存的连接器,例如Hazelcast和EHCache,但是如果您已经将Camel用作其他Red Hat产品的一部分,或者想了解LIRS驱逐如何胜过LRU,那么Infinispan值得尝试。

简而言之,Infinispan是事务性内存键值存储和数据网格。 在嵌入式模式下使用时,Infinispan与Camel驻留在同一JVM中,并允许Camel使用者接收缓存更改通知:

<route><from uri="infinispan://localhost?cacheContainer=#cacheContainer&caseName=orders&eventTypes=CACHE_ENTRY_CREATED"/><filter><simple>${out.header.CamelInfinispanIsPre} == true</simple><to uri="log:com.mycompany.order?showHeaders=true"/></filter>
</route>

在上面的示例中,当创建缓存条目时,Infinispan将触发两个事件-一个事件在创建缓存条目之前和之后。 也可以同步接收事件,即在处理高速缓存操作的同一线程中接收事件,或在不阻止高速缓存操作的情况下在单独的线程中异步接收事件。

将Infinispan用作本地缓存很简单,它公开了ConcurrentMap接口,并具有通常的到期,收回,钝化,持久存储,查询等功能。 使Infinispan成为数据网格的是节点发现其他节点以及在它们之间复制或分发数据的能力。 复制允许跨集群共享数据,而分发使用一致的哈希算法来实现更好的可伸缩性。

在客户端-服务器模式下,Infinispan作为独立应用程序运行,并且Camel生产者可以使用Infinispan的Hot Rod客户端发送消息。 Hot Rod是一种二进制,语言无关的智能协议,允许以拓扑结构和散列分布感知方式与Infinisnap服务器进行交互。

位于骆驼的Infinispan生产商目前提供GETPUTREMOVECLEAR操作。 这是生产者将数据放入订单缓存的示例:

<route><from uri="direct:orderCache"/><setHeader headerName="CamelInfinispanKey"><simple>${in.header.orderId}</simple></setHeader><setHeader headerName="CamelInfinispanValue"><simple>${in.header.orderTotal}</simple></setHeader><setHeader headerName="CamelInfinispanOperation"><simple>CamelInfinispanOperationPut</simple></setHeader><to uri="infinispan://localhost?caseName=orders"/>
</route>

让我们创建一个更有趣的示例。 Infinispan也符合JTA规范,可以参与交易。 我们将创建一个用于注册人员的REST API,该API将首先使用Camel sql组件将该人员持久保存在关系数据库中,然后在同一事务中将firstName放入Infinispan缓存中。 我们将使用事务处理的 Camel路由来做到这一点,因此,如果在路由过程中发生错误,在任何阶段,Camel都会确保回滚事务(用于缓存和数据库),以便数据库和缓存始终处于一致的状态。

<route><from uri="restlet:/persons?restletMethod=POST"/><transacted/><!-- PERSIST TO DB --><to uri="sql:insert into person(firstName, lastName) values(:#firstName,:#lastName)?dataSource=#dataSource"/><!-- DAMN EXCEPTION THROWER--><filter><simple>${in.header.lastName} == "damn"</simple><throwException ref="damn"/></filter><!-- PUT TO CACHE --><to uri="sql:select id from person WHERE id = (select max(id) from person)?dataSource=#dataSource"/><setHeader headerName="personId"><simple>${body[0][ID]}</simple></setHeader><setHeader headerName="CamelInfinispanKey"><simple>${headerAs(personId, String)}</simple></setHeader><setHeader headerName="CamelInfinispanValue"><simple>${in.header.firstName}</simple></setHeader><setHeader headerName="CamelInfinispanOperation"><simple>CamelInfinispanOperationPut</simple></setHeader><to uri="infinispan://localhost?cacheContainer=#cacheContainer&caseName=orders"/>
</route>

如您所见,路由中没有任何魔术或额外的配置,这是一条标准路由。 我们只有一小段代码,当该人的lastName被该死以模拟路线中间的错误时,将引发异常。

该应用程序使用atomikos JTA事务管理器以独立模式运行。 首先,我们创建一个JtaTransactionManager ,以供交易路线使用:

<bean id="userTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"/>
<bean id="userTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"/>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <constructor-arg ref="userTransaction"/><constructor-arg ref="userTransactionManager"/>
</bean>

然后用它包装我们的数据源

public AtomikosDataSourceBean atomikosDataSourceBean() throws Exception {EmbeddedXADataSource ds = new EmbeddedXADataSource();ds.setCreateDatabase("create");ds.setDatabaseName("target/testdb");ds.setUser("");ds.setPassword("");AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();xaDataSource.setXaDataSource(ds);xaDataSource.setUniqueResourceName("xaDerby");return xaDataSource;
}

并使用TransactionManagerLookup告诉Infinispan参与同一笔交易:

public BasicCacheContainer basicCacheContainer() throws Throwable {GlobalConfiguration glob = new GlobalConfigurationBuilder().nonClusteredDefault().build();Configuration loc = new ConfigurationBuilder().transaction().transactionMode(TransactionMode.TRANSACTIONAL).transactionManagerLookup(new TransactionManagerLookup() {@Overridepublic TransactionManager getTransactionManager() throws Exception {return jtaTransactionManager.getTransactionManager();}}).build();return new DefaultCacheManager(glob, loc, true);
}

完成所有这些样板代码之后,我们就有了数据源,缓存和Camel路由参与同一事务。 要查看具有两个阶段提交和回滚的完整REST示例,请从github获取源代码并进行使用。

BTW Camel-infinispan组件仍然不是Camel主干的一部分,要运行示例,您也将需要它 。

参考:来自OFBIZian博客的JCG合作伙伴 Bilgin Ibryam 提供的Infinispan的Camel事务缓存 。

翻译自: https://www.javacodegeeks.com/2013/08/transactional-caching-for-camel-with-infinispan.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367048.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“景驰科技杯”2018年华南理工大学程序设计竞赛 A. 欧洲爆破(思维+期望+状压DP)...

题目链接&#xff1a;https://www.nowcoder.com/acm/contest/94/A 题意&#xff1a;在一个二维平面上有 n 个炸弹&#xff0c;每个炸弹有一个坐标和爆炸半径&#xff0c;引爆它之后在其半径范围内的炸弹也会爆炸&#xff0c;每个炸弹最多爆炸一次&#xff0c;每次随机选一个未引…

java 日期是否合法_检测日期字符串是否为合法(java版)

1 /**2 * 检测日期字符串是否为合法3 *paramdateStr4 *paramformat5 *return6 */7 public static final boolean checkDateFormat(String dateStr,String format) throwsNumberFormatException{8 if(dateStr null || "".equals(dateStr) ) return false;9 if(dateSt…

从零开始搭建一个vue.js的脚手架

在谷歌工作的时候&#xff0c;我们要做很多界面的原型&#xff0c;要求快速上手&#xff0c;灵活运用&#xff0c;当时用的一些现有框架&#xff0c;比如angular&#xff0c;太笨重了——尤雨溪&#xff08;Vue.js 作者&#xff09; vue.js是现在一个很火的前端框架&#xff0c…

更安全的Web通信HTTPS

1. HTTP协议存在的问题 阅读本篇需要对HTTP协议有最基本的了解。 借用《图解密码技术》里的图片&#xff0c;我们以如下一个购物场景开始介绍&#xff1a; 在网购过程中&#xff0c;如果使用纯粹的HTTP协议&#xff0c;那么用户的账号密码&#xff0c;信用卡&#xff0c;银行卡…

Java中的Memento设计模式-示例教程

记忆模式是行为设计模式之一 。 当我们要保存对象的状态以便以后可以恢复时&#xff0c;可以使用Memento设计模式。 记忆模式用于以这种方式实现该目的&#xff0c;即在对象外部无法访问该对象的已保存状态数据&#xff0c;从而保护了已保存状态数据的完整性。 Memento模式通过…

CSS入门指南——页面的水平居中

我们经常看到这样的网页&#xff0c;即内容水平居中在屏幕中间&#xff0c;左右留白。我们来给这样的布局起个名字——水平居中布局 其实要实现这样的布局十分简单&#xff0c;即给中间部分一个宽度&#xff0c;设置margin左右值为auto,如&#xff0c;中间部分class"main&…

python控制台执行代码字符串_编写Python脚本以使用控制台命令执行

研究是在底部&#xff0c;阅读之前。。。谢谢。在我必须编写一个运行SQL查询的Python脚本。我创建了一个主类&#xff0c;名为SQLQuery。每个SQLQuery实例表示一个查询。脚本的结构必须如下所示&#xff1a;class SQLQuery(object):def __init___(self, string_myQuery)...inst…

Linux Tools Quick Tutorial 学习记录

总体 书籍链接 find命令 查找大于多少的文件 find / -type f -size 5M | xargs ls -lh | awk {print $5, $9} | ls -lrt

mysql explain的使用

一、explain返回各列的含义&#xff1a; 1、table&#xff1a;显示这一行的数据是关于那张表的 2、type&#xff1a;重要的列&#xff0c;显示连接使用了何种类型&#xff0c;从最好到最差的连接类型为const、eq_reg、ref、range、index、ALL 3、possible_keys&#xff1a;显示…

使用 Canvas 生成公众号头图

熟悉“前端晚自修”的朋友们应该知道&#xff0c;我们每期的头图除了上面的文字随着每期变动以外&#xff0c;几乎是一模一样的&#xff08;因为太懒了~&#xff09;。这个头图虽然丑了一点&#xff0c;但是也还说的过去&#xff0c;毕竟是我倾尽毕生艺术细胞拼出来的&#xff…

通过快速Java和文件序列化加快速度

从Java的第一个版本开始&#xff0c;每天都有许多开发人员试图至少达到与C / C 一样好的性能。 JVM供应商正在通过实现一些新的JIT算法来尽力而为&#xff0c;但仍有许多工作要做&#xff0c;尤其是在我们如何使用Java方面。 例如&#xff0c;对象<->文件序列化有很多优…

Flask mysql 模版传参_Flask渲染Jinja2模板和传参

### Flask渲染Jinja2模板和传参&#xff1a;1. 如何渲染模板&#xff1a;* 模板放在templates文件夹下* 从flask中导入render_template函数。* 在视图函数中&#xff0c;使用render_template函数&#xff0c;渲染模板。注意&#xff1a;只需要填写模板的名字&#xff0c;不需要…

08 Spring框架 AOP (一)

首先我们先来介绍一下AOP&#xff1a; AOP&#xff08;Aspect Orient Programming&#xff09;&#xff0c;面向切面编程&#xff0c;是面向对象编程OOP的一种补充。 面向对象编程是从静态角度考虑程序的结构&#xff0c;面向切面编程是从动态的角度考虑程序运行过程。 AOP底层…

使用Spring 3.2的DeferredResult进行长轮询

在我们的最后一集中 &#xff0c; Agile Cowboys Inc.的首席执行官刚刚雇用了Java / Spring顾问&#xff0c;方法是为他提供最初为女友购买的保时捷。 这位首席执行官的女友因失去保时捷而感到不安&#xff0c;已将其婚外情告诉了他的妻子。 他的妻子在分拆了CEO的套房后已申请…

移动spa商城优化记(一)---首屏优化篇

背景 随着公司业务的不断壮大&#xff0c;最近老是有用户反应公司APP内的商城打开比较慢&#xff0c;这可不行啊&#xff0c;慢了容易流失用户&#xff0c;流失用户减少公司业绩&#xff0c;公司业绩少我的年终奖就少…………&#xff0c;所以为了公司&#xff0c;也为了自己&a…

hprose for java 教程_hprose for java源码分析-4

4.1 疑窦丛生书接上回。上回说到&#xff0c;从HproseClient.java ------------------------- (#0)invokeHandler.handle()开始&#xff0c;将经历一个漫长的调用过程&#xff0c;下面把整个调用链粘出来&#xff0c;先认识下这个庞然大物。( >>> 表示调用到&#xff…

Git可视化极简易教程 — Git GUI使用方法

Git可视化极简易教程 — Git GUI使用方法 学习了&#xff1a;http://www.runoob.com/w3cnote/git-gui-window.html转载于:https://www.cnblogs.com/stono/p/9026292.html

如何用堆栈来保存和恢复滚动条位置

问题背景 在单页应用中&#xff0c;翻页一般通过display:none将先前的面板&#xff08;一般就是个div容器&#xff09;隐藏&#xff0c;然后将本次需要展现的面板设置成display:block&#xff08;当然&#xff0c;还可能加点css切换动画&#xff0c;不过不影响我们本次的讨论结…

如何在Hibernate中维护表的历史记录

为了维护数据库的历史记录或跟踪数据库表行的修改&#xff0c;我们创建了一个版本表&#xff0c;其中包含与原始表相同的字段。每当原始表被更改时&#xff0c;我们都会在版本表中创建另一个条目。 因此&#xff0c;对于每个更新查询&#xff0c;我们都必须在版本表中编写一个插…

java批量提取文件夹名称_bat 批量提取指定目录下的文件名

bat 批量提取指定目录下的文件名下面是批量获取指定目录下的文件名的核心代码echo offecho text inputset inputset /p input:echo %input% is inputcd %input%rem echo onfor %%a in (*) do (echo %%a is input)cd ..如下是sql server执行对应脚本文件sqlcmd -Spcserver -dmas…