更新数据库中的Apache Camel JPA对象会触发死锁

vngu2lb8  于 2023-10-20  发布在  Apache
关注(0)|答案(1)|浏览(176)

因此,我有一个Apache Camel路由,它从一个JPA端点读取Data元素,将它们转换为DataConverted元素,并通过另一个JPA端点将它们存储到另一个数据库中。
现在,我想在原始的Data元素上设置一个标志,表示它已成功复制。实现这一点的最佳方法是什么?
我试过了将该ID保存在context中,然后阅读该ID并访问.onCompletion().onCompleteOnly()中的dao方法。

from("jpa://Data")
        .onCompletion().onCompleteOnly().process(ex -> {    
            var id = Long.valueOf(getContext().getGlobalOption("id"));
            myDao().setFlag(id);
        }).end()
        .process(ex -> {
            Data data = ex.getIn().getBody(Data.class);
            DataConverted dataConverted = convertData(data);
            ex.getMessage().setBody(data);

            var globalOptions = getContext().getGlobalOptions();
            globalOptions.put("id", data.getId().toString());
            getContext().setGlobalOptions(globalOptions);
        })
        .to("jpa://DataConverted").end();

然而,这似乎触发了一个死锁,dao方法在提交更新时停顿。唯一的解释可能是Data对象被Camel锁定,并且仍然被锁定在路由的.onCompletion().onCompleteOnly()部分,因此它不能在那里被更新。
有没有更好的办法?

yvfmudvl

yvfmudvl1#

您是否尝试过使用收件人列表EIP,其中第一个目标是jpa:DataConverted端点,第二个目标将是设置标志的端点。这样,两个目标都将获得相同的消息,并将按顺序执行。
https://camel.apache.org/components/3.17.x/eips/recipientList-eip.html

from("jpa://Data")
   .process(ex -> {
            Data data = ex.getIn().getBody(Data.class);
            DataConverted dataConverted = convertData(data);
            ex.getIn().setBody(data);
     })
   .recipientList(constant("direct:DataConverted","direct:updateFlag"))
 .end();

 from("direct:DataConverted")
  .to("jpa://DataConverted")
 .end();

 from("direct:updateFlag")
  .process(ex -> {    
            var id = ((MessageConverted) ex.getIn().getBody()).getId();
            myDao().setFlag(id);
        })
 .end();

请记住,您可能希望通过添加.transacted()使路由具有事务性
https://camel.apache.org/components/3.17.x/eips/transactional-client.html

相关问题