标签: distributed-transactions

如何设计全局分布式事务(无数据库)?JTA可以用于无数据库事务吗?

我认为这是一个相当普遍的问题:如何将我的业务逻辑放在分布式系统环境中的全局事务中?举个例子,我有一个包含几个子任务的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,这是一个众所周知的分布式系统协议.

java jta distributed-transactions

16
推荐指数
2
解决办法
9107
查看次数

处理Oracle分布式数据库中LOB的最佳方法

如果创建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)

还有其他想法吗?

sql oracle dblink distributed-transactions

14
推荐指数
2
解决办法
4万
查看次数

ACID如何是两阶段提交协议?

我遇到了一种情况,我开始怀疑两阶段提交协议是否真的保证了ACID属性,特别是它的"A"部分.

让我们看一下涉及2个资源的理论分布式事务.(更多关于我必须处理的问题的实际描述可以在我的博客中找到).该场景是分布式事务的正常执行(无故障或恢复).应用程序启动事务,更新两个资源并发出commit()调用.提交完成后,应用程序将检查两个资源并查看已完成事务的所有更改.一切都很好,2PC协议完成了它的工作,对吧?

现在,对场景进行了一些小改动.当分布式事务正在执行commit()时,另一个应用程序将使用相同的2个资源.它只能看到交易的部分变化吗?假设,对第二个资源的更改尚未可见时,对一个资源的更改已经可见?

在我阅读过2PC协议的所有信息中,我找不到任何关于各个资源相对于彼此的变化可见性的保证.我找不到任何说明所有资源在同一时间完成各自提交的内容.

transactions distributed-transactions

13
推荐指数
2
解决办法
2739
查看次数

使用NHibernate和分布式事务导致"服务器无法恢复事务"的死锁

将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. 使用cmd.ExecuteNonQuery执行的查询被选为死锁牺牲品(我们可以在SQL事件探查器中看到它),但不会引发异常.
  2. session.Save失败,并显示错误消息"操作对事务状态无效".
  3. 每次执行此代码后,session.BeginTransaction都会失败.前几次,内部异常会有所不同(有时它是应该在步骤1中引发的死锁异常).最终它稳定到"服务器未能恢复交易.描述:3800000177." "不允许新请求启动,因为它应该带有有效的事务描述符."

如果单独使用,应用程序最终(在几秒或几分钟后)将从此条件恢复.

为什么步骤1中没有报告死锁异常?如果我们无法解决这个问题,那么我们如何防止我们的应用程序暂时无法使用?

该问题已在以下环境中重现

  • Windows 7 x64和Windows Server 2003 x86
  • SQL Server 2005和2008
  • .NET 4.0和3.5
  • NHibernate 3.2,3.1和2.1.2

我已经创建了一个测试夹具,有时会为我们重现这个问题.它可以在这里找到:http://wikiupload.com/EWJIGAECG9SQDMZ

sql-server nhibernate connection-pooling distributed-transactions

12
推荐指数
1
解决办法
9649
查看次数

AKKA远程演员是否可以在p2p swarm环境中使用?

我见过的Akka演员的大部分用例都是高性能的多核服务器或本地集群.

我很好奇它适用于更远程的高延迟高度失败的群体结构,如p2p网络.

我想到的应用程序将有关于群集节点的可信性和/或资源丰富性的规则,给予它们一些状态,就像bittorrent一样.它还需要能够尽可能地在整个群体中传播交易,但最终或部分一致性是可以接受的.可伸缩性比一致性更重要.

AKKA是建立这样的东西的潜在解决方案吗?它会比其他方法有任何特定的优点或缺点.

java scala distributed-computing distributed-transactions akka

12
推荐指数
1
解决办法
1032
查看次数

Spring Global事务与本地事务

阅读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

12
推荐指数
1
解决办法
1万
查看次数

银行交易如何"引导下" - 可能是详细的

我想知道银行交易是如何运作的.很难找到一些至少可以接受的解释.我不是指一些基本的分布式事务算法,而不是那些严肃的业务.

那么必须采取什么样的措施来保持一致性,从不放松一个便士.

那么国际交易,银行之间的交易呢.

整个世界的数据一致性 - 不是在纽约取出所有的钱,然后再次在东京重复..

在最近的历史中记录了哪些史诗般的失败?

我将非常感谢所有的答案.

algorithm distributed-computing banking distributed-transactions

11
推荐指数
1
解决办法
3526
查看次数

由于链接服务器的OLE DB提供程序“ SQLNCLI11”无法开始分布式事务,因此无法执行该操作

我正在尝试从我的计算机(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属性设置为以下内容(在两台服务器上) 在此处输入图片说明

  1. 从控制面板->服务(在两台服务器上)重新启动分布式事务处理协调器(MSDTC)。

  2. 卸载和安装的DTC(在两台服务器上)。

  3. 重新启动远程服务器。

  4. 关闭两台服务器上的防火墙。

  5. 在两个服务器上都启用了sp_configure'Ad Hoc Distributed Queries',1。

  6. 我运行了DTCPing,并成功ping通。

  7. 链接服务器的属性更改为以下内容: 在此处输入图片说明

还有什么可以尝试的?

更新:从另一台服务器到172.01.01.01运行事务。因此,问题不在目标服务器上,而是在源机器上。

sql-server msdtc distributed-transactions

11
推荐指数
3
解决办法
5万
查看次数

TransactionScope真正做了什么

调查一下,我验证了例如在下面的场景中没有回滚值"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是否只回滚与数据库相关的活动?或者事务可以管理其他事情,我不知道那些?"

c# transactions transactionscope distributed-transactions

10
推荐指数
1
解决办法
5442
查看次数

Spring/RabbitMQ:事务管理

为了简化我的问题,我有

App1与@Transactionnal方法createUser():

  • 在数据库中插入新用户
  • 在RabbitMQ中添加异步消息,以便用户收到通知邮件
  • (可能是一些额外的代码,但不多)

App2与RabbitMQ消息消失

  • 实时消除邮件队列中的消息
  • 读取数据库中的邮件数据
  • 发邮件

问题是,有时,App2尝试在App1上提交事务之前使用RabbitMQ消息.这意味着App2无法读取数据库上的邮件数据,因为尚未创建用户.

一些解决方案可能是:

  • 在App2上使用READ_UNCOMMITED隔离级别
  • 在RabbitMQ消息传递中添加一些延迟(或在消费者上添加一些RetryTemplate)
  • 改变我们发送电子邮件的方式......

我已经看到Spring中有一个RabbitTransactionManager,但我无法理解它应该如何工作.事务处理内容似乎总是有点难以理解,文档也没有那么多帮助.


有没有办法做这样的事情?

  • 在@Transactionnal方法中向RabbitMQ队列添加消息
  • 当事务结束时,消息将提交到队列,并且更改将提交到数据库
  • 这样在db事务结束之前无法消除消息

怎么样?如果我发送同步RabbitMQ消息而不是异步消息,那么可以期待什么呢?它会阻止等待响应的线程吗?因为我们确实为不同的用例发送同步和异步消息.

spring transactions distributed-transactions rabbitmq

10
推荐指数
1
解决办法
1820
查看次数