使用 Spring 和 Hibernate 跨多个数据库进行分布式事务的“最佳"方法是什么 [英] What is the 'best' way to do distributed transactions across multiple databases using Spring and Hibernate

查看:21
本文介绍了使用 Spring 和 Hibernate 跨多个数据库进行分布式事务的“最佳"方法是什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序 - 更像是一个实用程序 - 它位于角落并定期更新两个不同的数据库.

I have an application - more like a utility - that sits in a corner and updates two different databases periodically.

这是一个使用 Spring 应用程序上下文构建的小型独立应用程序.上下文中配置了两个 Hibernate Session Factories,依次使用 Spring 中配置的 Commons DBCP 数据源.

It is a little standalone app that has been built with a Spring Application Context. The context has two Hibernate Session Factories configured in it, in turn using Commons DBCP data sources configured in Spring.

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

Currently there is no transaction management, but I would like to add some. The update to one database depends on a successful update to the other.

该应用程序不位于 Java EE 容器中 - 它由从 shell 脚本调用的静态启动器类引导.启动器类实例化应用程序上下文,然后调用它的一个 bean 上的方法.

The app does not sit in a Java EE container - it is bootstrapped by a static launcher class called from a shell script. The launcher class instantiates the Application Context and then invokes a method on one of its beans.

将事务性置于数据库更新的最佳"方法是什么?

What is the 'best' way to put transactionality around the database updates?

我会将最佳"的定义留给您,但我认为它应该是易于设置"、易于配置"、便宜"和易于打包和重新分发"的某些功能.自然自由开放源码软件会很好.

I will leave the definition of 'best' to you, but I think it should be some function of 'easy to set up', 'easy to configure', 'inexpensive', and 'easy to package and redistribute'. Naturally FOSS would be good.

推荐答案

在多个数据库上分发事务的最佳方式是:不要.

The best way to distribute transactions over more than one database is: Don't.

有些人会将您指向 XA,但 XA(或两阶段提交)是谎言(或市场营销).

Some people will point you to XA but XA (or Two Phase Commit) is a lie (or marketese).

想象一下:在第一阶段告诉 XA 管理器它可以发送最终提交后,与其中一个数据库的网络连接失败.怎么办?暂停?这将使其他数据库损坏.回滚?两个问题:你不能回滚一个提交,你怎么知道第二个数据库发生了什么?可能是数据提交成功后网络连接失败,只丢失了成功"信息?

Imagine: After the first phase have told the XA manager that it can send the final commit, the network connection to one of the databases fails. Now what? Timeout? That would leave the other database corrupt. Rollback? Two problems: You can't roll back a commit and how do you know what happened to the second database? Maybe the network connection failed after it successfully committed the data and only the "success" message was lost?

最好的方法是将数据复制到一个地方.使用允许您随时中止复制并继续复制的方案(例如,忽略您已有的数据或按 ID 排序选择并仅请求副本的记录 > MAX(ID)).通过交易保护这一点.这不是问题,因为您只是从源读取数据,因此当事务因任何原因失败时,您可以忽略源数据库.因此,这是一个普通的旧单源交易.

The best way is to copy the data in a single place. Use a scheme which allows you to abort the copy and continue it at any time (for example, ignore data which you already have or order the select by ID and request only records > MAX(ID) of your copy). Protect this with a transaction. This is not a problem since you're only reading data from the source, so when the transaction fails for any reason, you can ignore the source database. Therefore, this is a plain old single source transaction.

复制数据后,在本地进行处理.

After you have copied the data, process it locally.

这篇关于使用 Spring 和 Hibernate 跨多个数据库进行分布式事务的“最佳"方法是什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆