-->

什么是“最好”的方式做跨使用Spring和Hibernate多个数据库的分布式事务(What is

2019-06-18 12:30发布

我有一个应用程序 - 更像是一个工具 - 那坐在一个角落里,并更新两个不同的数据库定期。

这是已建成使用Spring应用程序上下文一点独立的应用程序。 上下文中有两个配置Hibernate Session的工厂,转而使用在Spring配置下议院DBCP数据源。

目前还没有事务管理,但我想补充一些。 一个数据库更新取决于成功更新到另一个。

该应用程序不坐在Java EE容器 - 它是由一个shell脚本称为静态启动自举类。 启动器类实例化应用上下文,然后调用它的豆中的一个的方法。

什么是“最好”的方式把事务性周围的数据库的更新?

我会离开的“最佳”给你的定义,但我认为这应该是“容易建立”,“易于配置”,“廉价”和“容易包装和重新分配”的一些功能。 当然FOSS将是一件好事。

Answer 1:

超过一个以上的数据库分布事务的最好办法是:不。

有些人会指向你XA但XA(或两个阶段提交)是骗人的(或marketese)。

试想一下:第一个阶段已经告诉XA管理器后,它可以发送最后的提交,通过网络连接到数据库的一个失败。 怎么办? 超时? 这将使其他数据库损坏。 回滚? 两个问题:您不能回滚提交和你怎么知道发生了什么事到第二个数据库? 也许网络连接失败是成功提交该数据,只有“成功”的消息后,失去了什么?

最好的办法是在一个地方的数据复制。 使用方案,该方案可以让你放弃副本,并继续在任何时间(例如,忽略,你已经或ORDER BY ID的选择,并要求只记录> MAX(副本的ID)的数据)。 与交易保护此。 这不是一个问题,因为你只从源中读取数据,因此当交易由于某种原因失败时,可以忽略源数据库。 因此,这是一个普通的旧单个源事务。

之后你在本地复制的数据,对其进行处理。



Answer 2:

安装在您的上下文中的事务管理器。 春天文档刚才的例子,这是非常简单的。 然后,当你要执行一个交易:

try { 
    TransactionTemplate tt = new TransactionTemplate(txManager);

    tt.execute(new TransactionCallbackWithoutResult(){
    protected void doInTransactionWithoutResult(
            TransactionStatus status) {
        updateDb1();
        updateDb2();
    }
} catch (TransactionException ex) {
    // handle 
}

更多的例子,以及信息也许看看这个: 使用Spring XA交易



Answer 3:

当你说“两个不同的数据库”,你的意思是不同的数据库服务器,或在同一数据库服务器中的两个不同的模式?

如果是前者,那么如果你想完全事务性,那么你需要的XA事务API,它提供了完整的两阶段提交。 但更重要的是,你还需要一个事务协调器/监测器,其管理的不同数据库系统之间的事务传播。 这是JavaEE规范,而在这一点相当稀薄部分的一部分。 该TX协调本身是一个复杂的软件。 你的应用软件(通过Spring,如果你愿意的话)会谈协调。

但是,如果你仅仅意味着在同一数据库服务器内的两个数据库,然后香草JDBC事务应该工作得很好,只是一个单一的事务中对两种数据库执行的操作。



Answer 4:

在这种情况下,你需要一个事务监视器(服务器支持XA协议),并确保你的数据库支持XA还。 大多数(?全部)的J2EE服务器有自带的事务监视器如果您的代码在J2EE服务器没有运行,然后有一堆独立的替代品 - Atomicos,Bitronix等。



Answer 5:

你可以尝试春天ChainedTransactionManager - http://docs.spring.io/spring-data/commons/docs/1.6.2.RELEASE/api/org/springframework/data/transaction/ChainedTransactionManager.html支持分布式数据库的事务。 这可能是XA一个更好的选择



文章来源: What is the 'best' way to do distributed transactions across multiple databases using Spring and Hibernate