如何在Java中创建多数据库事务?

时间:2016-08-26 19:44:57

标签: java spring oracle hibernate jndi

情境:

  • DB1和DB2每个都有一个表“T1”
  • 当我在服务上调用insert(..)方法时,我需要更新两个数据库表。
  • 如果其中一个数据库的更新失败,则它们都需要ROLLBACK。

调查:

  • JTA分布式交易 - 没有太多运气了。

服务电话:

@Transactional(value="twoDBTransactionManager")
public class Service {
    TwoDBTransMgr tm = new TwoDBTransMgr(DB1, DB2);

    /** Option #1 **/
    public void updateBoth(id, value) {
        tm.updateBothAndCommit(id, value);
    }

    /** Option #2 **/
    public void update(id, value) {
        tm.updateDB1(id, value);
        tm.updateDB2(id, value);
        tm.commitBoth();
    }

服务实施伪代码:

<jee:jndi-lookup id="db1" jndi-name="jdbc/db1" resource-ref="true" proxy-interface="javax.sql.DataSource"/>
<jee:jndi-lookup id="db2" jndi-name="jdbc/db2" resource-ref="true" proxy-interface="javax.sql.DataSource"/>

申请背景

DECLARE
BEGIN
  INSERT INTO t1@TESTLINK (val) VALUES ('DB LINK');
  INSERT INTO t1 (val) VALUES ('NO DB LINK');
  COMMIT;
EXCEPTION WHEN OTHERS THEN
  ROLLBACK;
  RAISE;
END;
/

技术:

Oracle 12c,Java 6,Spring,Maven,Hibernate,JNDI

PL / SQL等效解决方案:

  @NamedQuery(name = "Payment.byAmount",
      query = "select p from Payment as p join p.application as a where p.amount = ?1 and p.channel = ?2 and p.type =?3 and p.created = ?4 and p.deletedDate is null and a.uuid = ?5")

2 个答案:

答案 0 :(得分:0)

之前我对此主题进行过相同的研究。似乎没有直接的方法来实现。

如果DB1和DB2使用相同的数据库系统(让我们说oracle)。我认为使用DB Link做这件事会更好。

这意味着,您使用单个数据源来访问两个数据库中的表。

答案 1 :(得分:0)

我认为消息可能是一种解决这个问题的方法。说,A,B是两个DB连接。他们不能互相认识。我们需要另一个组成部分来沟通。

让我们说:在交易之前,A,B向C发送一个消息,然后进行一些操作,然后发送一个msg到c来告诉是否正常。然后C将一个msg发送给A,B,它定义了事务提交或回滚。

就像:

开始:

一个----&GT; ç

乙----&GT; C

向C发送一个消息,告诉C帮助观察运营商

操作:

A:做一些操作,而不是

A ---&gt; C告诉C操作成功或失败

B:做一些操作,而不是

B ---&gt; C告诉C操作成功或失败

A,B保持,在向C发送消息后,等待单一形式C

结束:

Ç---&GT;甲

Ç---&GT;乙

告诉A,B,提交或回滚