我认为这是一个相当普遍的问题:如何将我的业务逻辑放在分布式系统环境中的全局事务中?举个例子,我有一个包含几个子任务的TaskA:
TaskA {subtask1,subtask2,subtask3 ...}
这些子任务中的每一个都可以在本地机器或远程机器上执行,我希望TaskA通过事务以原子方式(成功或失败)执行.每个子任务都有一个回滚函数,一旦TaskA认为操作失败(因为其中一个子任务失败),它就会调用子任务的每个回滚函数.否则,TaskA会提交整个事务.
为此,我按照"审计试用"事务模式来记录每个子任务,因此TaskA可以知道子任务的操作结果,然后决定回滚或提交.这听起来很简单,但是,困难的部分是如何将每个子任务与全局事务相关联?
当TaskA开始时,它启动一个关于哪个子任务什么都不知道的全局事务.为了使子任务意识到它,我必须将事务上下文传递给每个子任务调用.这真是太可怕了!我的子任务可以在新线程中执行,也可以通过AMQP代理发送消息在远程执行,很难巩固上下文传播的方式.
我做了一些研究,如"交易模式 - 四个交易相关模式的集合","异步消息传递环境中的已检查事务",这些都没有解决我的问题.他们要么没有实际的例子,要么没有解决上下文传播问题.
我想知道人们如何解决这个问题 因为这种交易必须在企业软件中很常见.
X/Open XA只是解决方案吗?JTA可以在这里提供帮助(我没有考虑JTA,因为它与数据库事务有关,我使用Spring,我不想在我的软件中涉及另一个Java EE应用服务器).
有些专家可以和我分享一些想法吗?谢谢.
Arjan和Martin给出了非常好的答案,谢谢.最后我没有这样做.经过更多的研究,我选择了另一种模式" CheckPoint " 1.
根据我的要求,我发现我的"审核试验事务模式"的意图是知道操作已进行到哪个级别,如果失败,我可以在重新加载某些上下文后在失败的地点重新启动它.实际上这不是事务,它在失败后没有回滚其他成功的步骤.这是CheckPoint模式的精髓.然而,研究分布式交易的东西让我学到了很多有趣的东西.除了Arjan和Martin提到的.我还建议人们深入研究这个领域,看看CORBA,这是一个众所周知的分布式系统协议.
如果创建Oracle dblink,则无法直接访问目标表中的LOB列.
例如,您使用以下命令创建dblink:
create database link TEST_LINK
connect to TARGETUSER IDENTIFIED BY password using 'DATABASESID';
Run Code Online (Sandbox Code Playgroud)
在此之后,您可以执行以下操作:
select column_a, column_b
from data_user.sample_table@TEST_LINK
Run Code Online (Sandbox Code Playgroud)
除非列是LOB,否则会出现错误:
ORA-22992: cannot use LOB locators selected from remote tables
Run Code Online (Sandbox Code Playgroud)
这是一个记录在案的限制.
同一页面建议您将值提取到本地表中,但这有点麻烦:
CREATE TABLE tmp_hello
AS SELECT column_a
from data_user.sample_table@TEST_LINK
Run Code Online (Sandbox Code Playgroud)
还有其他想法吗?
我遇到了一种情况,我开始怀疑两阶段提交协议是否真的保证了ACID属性,特别是它的"A"部分.
让我们看一下涉及2个资源的理论分布式事务.(更多关于我必须处理的问题的实际描述可以在我的博客中找到).该场景是分布式事务的正常执行(无故障或恢复).应用程序启动事务,更新两个资源并发出commit()调用.提交完成后,应用程序将检查两个资源并查看已完成事务的所有更改.一切都很好,2PC协议完成了它的工作,对吧?
现在,对场景进行了一些小改动.当分布式事务正在执行commit()时,另一个应用程序将使用相同的2个资源.它只能看到交易的部分变化吗?假设,对第二个资源的更改尚未可见时,对一个资源的更改已经可见?
在我阅读过2PC协议的所有信息中,我找不到任何关于各个资源相对于彼此的变化可见性的保证.我找不到任何说明所有资源在同一时间完成各自提交的内容.
将NHibernate与分布式事务一起使用时,我们遇到了问题.
请考虑以下代码段:
//
// There is already an ambient distributed transaction
//
using(var scope = new TransactionScope()) {
using(var session = _sessionFactory.OpenSession())
using(session.BeginTransaction()) {
using(var cmd = new SqlCommand(_simpleUpdateQuery, (SqlConnection)session.Connection)) {
cmd.ExecuteNonQuery();
}
session.Save(new SomeEntity());
session.Transaction.Commit();
}
scope.Complete();
}
Run Code Online (Sandbox Code Playgroud)
有时,当服务器处于极端负载时,我们将看到以下内容:
如果单独使用,应用程序最终(在几秒或几分钟后)将从此条件恢复.
为什么步骤1中没有报告死锁异常?如果我们无法解决这个问题,那么我们如何防止我们的应用程序暂时无法使用?
该问题已在以下环境中重现
我已经创建了一个测试夹具,有时会为我们重现这个问题.它可以在这里找到:http://wikiupload.com/EWJIGAECG9SQDMZ
sql-server nhibernate connection-pooling distributed-transactions
我见过的Akka演员的大部分用例都是高性能的多核服务器或本地集群.
我很好奇它适用于更远程的高延迟和高度失败的群体结构,如p2p网络.
我想到的应用程序将有关于群集节点的可信性和/或资源丰富性的规则,给予它们一些状态,就像bittorrent一样.它还需要能够尽可能地在整个群体中传播交易,但最终或部分一致性是可以接受的.可伸缩性比一致性更重要.
AKKA是建立这样的东西的潜在解决方案吗?它会比其他方法有任何特定的优点或缺点.
java scala distributed-computing distributed-transactions akka
阅读Spring事务文档时,我发现它支持全局事务和本地事务.
如果我使用以下配置 - 它是否意味着它是本地事务?
<tx:annotation-driven transaction-manager="transManager" />
<bean id="transManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>
Run Code Online (Sandbox Code Playgroud)
我尝试在Google和Stackoverflow中搜索,但没有得到任何资源解释相同的简单术语.
java spring transactions distributed-transactions spring-transactions
我想知道银行交易是如何运作的.很难找到一些至少可以接受的解释.我不是指一些基本的分布式事务算法,而不是那些严肃的业务.
那么必须采取什么样的措施来保持一致性,从不放松一个便士.
那么国际交易,银行之间的交易呢.
整个世界的数据一致性 - 不是在纽约取出所有的钱,然后再次在东京重复..
在最近的历史中记录了哪些史诗般的失败?
我将非常感谢所有的答案.
algorithm distributed-computing banking distributed-transactions
我正在尝试从我的计算机(SQL Server 2012)到客户端服务器(SQL Server 2008)运行分布式事务。
我正在尝试运行:
begin distributed transaction
select * from [172.01.01.01].master.dbo.sysprocesses
Commit Transaction
Run Code Online (Sandbox Code Playgroud)
我得到:
OLE DB provider "SQLNCLI11" for linked server "172.01.01.01" returned message "No transaction is active.".
Msg 7391, Level 16, State 2, Line 2
The operation could not be performed because OLE DB provider "SQLNCLI11" for linked server "172.01.01.01" was unable to begin a distributed transaction.
Run Code Online (Sandbox Code Playgroud)
我可以在服务器返回数据的情况下对它运行SELECT,因此至少我知道服务器可以互相看见,并且链接服务器存在并且正在运行
现在,网络上有很多与此相关的帖子,但我无法使其正常运行。到目前为止,这是我尝试过的操作:1.将DTC属性设置为以下内容(在两台服务器上)

从控制面板->服务(在两台服务器上)重新启动分布式事务处理协调器(MSDTC)。
卸载和安装的DTC(在两台服务器上)。
重新启动远程服务器。
关闭两台服务器上的防火墙。
在两个服务器上都启用了sp_configure'Ad Hoc Distributed Queries',1。
我运行了DTCPing,并成功ping通。
链接服务器的属性更改为以下内容:

还有什么可以尝试的?
更新:从另一台服务器到172.01.01.01运行事务。因此,问题不在目标服务器上,而是在源机器上。
调查一下,我验证了例如在下面的场景中没有回滚值"myInt"
int myInt = 10;
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
myInt=20;
Transaction t = Transaction.Current;
t.Rollback();
}
Run Code Online (Sandbox Code Playgroud)
所以它让我想到"TransactionScope是否只回滚与数据库相关的活动?或者事务可以管理其他事情,我不知道那些?"
为了简化我的问题,我有
App1与@Transactionnal方法createUser():
App2与RabbitMQ消息消失
问题是,有时,App2尝试在App1上提交事务之前使用RabbitMQ消息.这意味着App2无法读取数据库上的邮件数据,因为尚未创建用户.
一些解决方案可能是:
我已经看到Spring中有一个RabbitTransactionManager,但我无法理解它应该如何工作.事务处理内容似乎总是有点难以理解,文档也没有那么多帮助.
有没有办法做这样的事情?
怎么样?如果我发送同步RabbitMQ消息而不是异步消息,那么可以期待什么呢?它会阻止等待响应的线程吗?因为我们确实为不同的用例发送同步和异步消息.