如何在涉及jdbc,jms和web服务的java中执行分布式事务

时间:2013-12-07 16:39:22

标签: java transactions

我在接受采访时被问到以下问题但无法回答。

如何在单个事务中包含jdbc操作,Web服务调用和JMS操作。这意味着如果其中一个失败,则必须全部回滚。

在涉及多个数据库的数据库事务的情况下,我听说过两阶段提交协议和oracl XA。但不确定这里是否可以使用相同的内容。

5 个答案:

答案 0 :(得分:5)

关键因素是您连接的Web服务是使用支持事务的Web服务框架构建的。 JBoss Narayana就是这样一个Web服务框架。一旦您连接的Web服务端点在这样的框架上,只需配置spring即可使用适当的客户端。

对于Narayana,弹出配置(来自http://bgshinhung.blogspot.ca/2012/10/integrating-spring-framework-jetty-and.html)用于与Web服务的交易:

   

答案 1 :(得分:1)

由于系统是分开的,你永远无法以完全防弹的方式做到这一点。系统的一个阶段中的失败(例如,在SQL提交和JMS提交之间,服务器上的电源被关闭)将使SQL提交到位。

解决这个问题的唯一方法是在某处保留部分提交记录并在启动时扫描以修复任何导致的问题,但现在如果处理失败或保留该列表会发生什么。

基本上,解决方案是自己实现多阶段提交和回滚过程,包含您需要进行的三个操作。如果任何操作失败,那么您需要反转(最好使用内部事务机制,如果没有,则通过发出反转命令)到目前为止已完成的任何操作。

虽然有很多极端情况和类似系统的潜在方法会失败,所以第一种方法应该是考虑是否可以重新设计系统,这样根本不需要这样做! / p>

答案 2 :(得分:0)

这可能是技巧问题,正确的答案是“它无法完成”。

但我会尝试使用这样的代码:

try{
jdbc.startTransaction();
Savepoint saveJdbc = jdbc.setSavepoint();
JMS.startTransaction();
Savepoint saveJMS = JMS.setSavepoint();
jdbs.doSomeStuff();
JMS.doSomeStuff();
jdbc.commit();
JMS.commit(); 
if(webServise.doSomeStuff() == fail){throw new Exception();} 
}
catch(Eception e){
jdbc.rollback(saveJdbc);
JMS.rollback(saveJMS);
}

您准备了一个已回滚的服务。您准备第二个已回滚的服务。您将尝试Web服务,如果Web服务失败,您将回滚那两个已回滚的服务。

可能是实现回滚到您的Web服务的一种方法。

答案 3 :(得分:0)

我们有同样的情况,比如Web服务会推送数据,我们必须读取xml流并持久化到db(oracle)。我们遵循的实施是。

  1. Web服务发送soap消息,其中包含xml流数据。
  2. 将所有请求肥皂消息推送到jms。
  3. 相应的列表器将读取流并将数据保存到“临时表”中。
  4. 如果请求处理成功,则将数据从临时表移动到实际表。
  5. 如果有任何错误回滚。

    希望以上几点可能有所帮助。

答案 4 :(得分:0)

在我看来,面试官似乎喜欢理解你在企业范围内分配的思考能力。几点:

  1. JDBC 用于数据库连接
  2. WebService 可能是一种将控制命令发送到的机制 来自任何客户的服务器。
  3. JMS 主要用于警告正在发生的事情 系统。
  4. 我的猜测是你的面试官可能有一个典型的场景,他希望能满足以下情况:

    数据位于一个层(群集或计算机)上 客户可以是任何类型,移动,应用程序,ios,目标c,浏览器支付等。 JMS配置为侦听主题。或者他希望他能做到这一点。

    现在可能最好的方法是编写一个JMS订阅者,它决定在onMessage()方法中做什么。 例如,假设从客户端启动了Web服务的付款请求。这将启动JMS发布者告诉DAO执行与数据库的必要内部连接,并且当事务处于中间时以及何时完成,将向订阅者发布一条消息。您将对每个步骤进行全面控制,因为它将配置为通过JMS发布。虽然这很难实现,但这可能是您面试官的预期方法。 (这只是我的猜测,请注意。)