标签: distributed-transactions

无法开始分布式事务

我正在尝试对链接服务器运行SQL,但我得到了错误.

BEGIN DISTRIBUTED TRANSACTION
SELECT TOP 1 * FROM Sessions


OLE DB provider "SQLNCLI" for linked server "ASILIVE" returned message "No transaction is active.".

Msg 7391, Level 16, State 2, Line 3
The operation could not be performed because OLE DB provider "SQLNCLI" for linked server "ASILIVE" was unable to begin a distributed transaction.
Run Code Online (Sandbox Code Playgroud)

提供程序返回了两个错误:

错误#1:

Number: $80040E14
Source: Microsoft OLE DB Provider for SQL Server
Description: OLE DB provider "SQLNCLI" for linked server "ASILIVE" returned message "No transaction is …
Run Code Online (Sandbox Code Playgroud)

sql-server msdtc sql-server-2005 distributed-transactions

89
推荐指数
3
解决办法
16万
查看次数

两阶段提交如何防止最后一秒失败?

我正在研究两阶段提交如何在分布式事务中工作.据我所知,在阶段的最后阶段,事务协调器会询问每个节点是否准备好提交.如果每个人都同意,那么它会告诉他们继续并提交.

是什么阻止了以下失败?

  1. 所有节点都响应它们已准备好提交
  2. 事务协调器告诉他们"继续并提交",但其中一个节点在收到此消息之前崩溃
  3. 所有其他节点成功提交,但现在分布式事务已损坏
  4. 我的理解是,当崩溃的节点返回时,它的事务将被回滚(因为它从未得到提交消息)

我假设每个节点都运行一个普通的数据库,该数据库对分布式事务一无所知.我错过了什么?

database distributed-transactions

64
推荐指数
5
解决办法
7842
查看次数

两阶段提交

我相信大多数人都知道2PC(两阶段提交协议)是什么以及如何在Java或大多数现代语言中使用它.基本上,当您有2个或更多DB时,它用于确保事务处于同步状态.

假设我有两个DB(A和B)在两个不同的位置使用2PC.在A和B准备提交事务之前,两个DB都将向事务管理器报告,说它们已准备好提交.因此,当事务管理器被确认时,它将向A和B发送信号,告诉它们继续.

这是我的问题:让我们说A收到信号并提交交易.一切都完成后,B即将做同样的事情,但有人拔掉电源线,导致整个服务器关闭.当B重新上线时,B会做什么?B怎么做呢?

记住,A是承诺但B不是,我们正在使用2PC(因此,2PC的设计停止工作,不是吗?)

database distributed-transactions

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

什么是"分布式交易"?

维基百科有关分布式事务的文章不是很有帮助.

您能否对分布式事务的内容进行高级描述?

另外,您能举例说明为什么应用程序或数据库应该执行更新两台或多台联网计算机上的数据的事务吗?我理解了经典的银行例子; 我更关心像Dynamo,Bigtable,HBase或Cassandra这样的Web规模数据库中的分布式事务.

database commit xa distributed-transactions

26
推荐指数
3
解决办法
2万
查看次数

Kafka - 如何使用高级消费者在每条消息之后提交偏移量?

我正在使用Kafka的高级消费者.因为我正在使用Kafka作为我的应用程序的"事务队列",所以我需要确保我不会错过或重读任何消息.我有两个问题:

  1. 如何将偏移量提交给zookeeper?在每次成功使用消息后,我将关闭自动提交和提交偏移量.我似乎无法找到如何使用高级消费者执行此操作的实际代码示例.谁能帮我这个?

  2. 另一方面,我听说承诺动物园管理员可能会很慢,所以另一种方式可能是在本地跟踪偏移?这种替代方法是否可取?如果是的话,你会怎么做?

message-queue distributed-transactions apache-kafka apache-zookeeper

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

在提交事务之前传递JMS消息

我有一个非常简单的场景,涉及应用程序服务器(Glassfish)中的数据库JMS.场景很简单:

1. an EJB inserts a row in the database and sends a message.
2. when the message is delivered with an MDB, the row is read and updated. 
Run Code Online (Sandbox Code Playgroud)

问题是有时在数据库中提交插入之前传递消息.如果我们考虑2阶段提交协议,这实际上是可以理解的:

1. prepare JMS
2. prepare database
3. commit JMS
4. ( tiny little gap where message can be delivered before insert has been committed)
5. commit database
Run Code Online (Sandbox Code Playgroud)

和其他人讨论过这个问题,但答案总是如此:"奇怪,它应该开箱即用".

我的问题是:

  • 它怎么能开箱即用?
  • 我的场景听起来很简单,为什么没有更多人遇到类似的麻烦?
  • 难道我做错了什么?有没有办法正确解决这个问题?

以下是关于我对问题的理解的更多细节:

只有在按此顺序处理参与者时才存在此计时问题.如果2PC以相反的顺序(数据库优先,然后是消息代理)处理参与者应该没问题.这个问题是随机发生的,但完全可以重现.

我发现无法在Glassfish文档中控制JTA,JCA和JPA规范中分布式事务中参与者的顺序.我们可以假设它们将在使用它们时按照顺序登记在分布式事务中,但是使用诸如JPA之类的ORM,很难知道何时刷新数据以及何时真正使用数据库连接.任何的想法?

database jms 2phase-commit distributed-transactions java-ee

20
推荐指数
1
解决办法
4249
查看次数

TransactionScope:避免分布式事务

我有一个父对象(DAL的一部分),其中包含List<t>子对象的collection().

当我将对象保存回DB时,我输入/更新父对象,然后循环遍历每个子对象.为了可维护性,我将孩子的所有代码放入一个单独的私有方法中.

我打算使用标准的ADO事务,但在我的旅行中,我偶然发现了TransactionScope对象,我相信这将使我能够在一个事务中将父方法中的所有数据库交互(以及子方法中的所有交互)包装起来.

到现在为止还挺好..?

所以接下来的问题是如何在TransactionScope中创建和使用连接.我听说使用多个连接,即使它们是相同的DB也可以强制TransactionScope认为它是一个分布式事务(涉及一些昂贵的DTC工作).

是这样吗?或者,正如我似乎在其他地方读到的那样,使用相同的连接字符串(它将自己用于连接池)的情况会好吗?

更实际的是,我......

  1. 在父和子中创建单独的连接(尽管具有相同的连接字符串)
  2. 在父项中创建一个连接作为参数传递它(对我来说似乎很笨拙)
  3. 做点什么......?

更新:

虽然看起来我可以使用我常用的.NET3.5 +和SQL Server 2008+,但是这个项目的另一部分将使用Oracle(10g),所以我不妨练习一种可以跨项目使用的技术.

所以我只是简单地将连接传递给子方法.


选项1代码示例:

using (TransactionScope ts = new TransactionScope())
            {
                using (SqlConnection conn = new SqlConnection(connString))
                {
                    using (SqlCommand cmd = new SqlCommand())
                    {
                        cmd.Connection = conn;
                        cmd.Connection.Open();
                        cmd.CommandType = CommandType.StoredProcedure;

                        try
                        {
                            //create & add parameters to command

                            //save parent object to DB
                            cmd.ExecuteNonQuery();

                            if ((int)cmd.Parameters["@Result"].Value != 0)
                            {
                                //not ok
                                //rollback transaction
                                ts.Dispose();
                                return false;
                            }
                            else //enquiry saved OK
                            {
                                if …
Run Code Online (Sandbox Code Playgroud)

c# transactions transactionscope distributed-transactions

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

三阶段提交如何避免阻塞?

我试图了解三阶段提交如何避免阻塞

请考虑以下两种故障情况:

场景1:在阶段2中,协调器向所有群组发送预提交消息,并且从群组A以外的所有群组获得确认.网络问题阻止群​​组A接收协调器的预提交消息.群组A超时等待预提交消息并选择中止.然后协调员和队列A都崩溃了.

场景2:协议到达阶段3.协调器向队列A发送doCommit消息.但在它发送更多的doCommit消息之前,协调器崩溃.群组A提交其部分事务然后崩溃.

据我所知,剩下的同类群体在场景1和场景2结束时具有完全相同的状态.因此,当恢复协调员介入时,如何从剩余队列中找出我们是否在场景1中并且中止或我们在方案2和提交,从而避免阻止?

2phase-commit distributed-transactions

19
推荐指数
4
解决办法
3567
查看次数

在数据库和Kafka生产者之间同步事务

我们有一个微服务架构,其中Kafka用作服务之间的通信机制。一些服务具有自己的数据库。假设用户调用服务A,这将导致在该服务的数据库中创建一条记录(或一组记录)。此外,此事件应作为Kafka主题的一项报告给其他服务。确保仅在成功更新Kafka主题(实质上是围绕数据库更新和Kafka更新创建分布式事务)时才写入数据库记录的最佳方法是什么?

我们正在考虑使用spring-kafka(在Spring Boot WebFlux服务中),我可以看到它具有KafkaTransactionManager,但是据我了解,这更多地是关于Kafka交易本身(确保Kafka生产者和消费者之间的一致性),而不是在两个系统之间同步事务(请参见此处:“ Kafka不支持XA,您必须处理在Kafka tx回滚时DB tx可能提交的可能性。”)。另外,我认为此类依赖于Spring的事务框架,至少就我目前所知,该框架是线程绑定的,如果使用反应性方法(例如WebFlux)在操作的不同部分执行该方法,则该类将无法工作。不同的线程。(我们正在使用react-pg-client,因此是手动处理事务,而不是使用Spring的框架。)

我能想到的一些选择:

  1. 不要将数据写入数据库:仅将其写入Kafka。然后使用使用者(在服务A中)更新数据库。看来这可能不是最有效的,并且会出现问题,因为用户调用的服务无法立即看到它应该刚刚创建的数据库更改。
  2. 不要直接写到Kafka:只写数据库,并使用Debezium之类的东西向Kafka报告更改。这里的问题是,更改是基于单个数据库记录的,而要存储在Kafka中的重要业务事件可能涉及多个表中数据的组合。
  3. 首先写入数据库(如果失败,则不执行任何操作,仅引发异常)。然后,在写入Kafka时,假设写入可能会失败。使用内置的自动重试功能可以使其保持尝试一段时间。如果最终完全失败,请尝试写入死信队列,并为管理员创建某种手动机制以将其解决。而且,如果写入DLQ失败(即Kafka完全关闭),只需以其他方式(例如,记录到数据库)进行记录,然后再次创建某种手动机制供管理员进行分类即可。

是否有人对以上内容有任何想法或建议,或者能够纠正上述假设中的任何错误?

提前致谢!

distributed-transactions spring-transactions apache-kafka spring-kafka

17
推荐指数
3
解决办法
3727
查看次数

三阶段提交

我理解三阶段提交是为了解决"两阶段提交"的问题,当在第二阶段协调器和队列同时失败时,不可能知道协调器是否已决定提交消息.

显然,三阶段提交旨在通过添加额外阶段来解决此问题.但是,如果协调员和队列失败,你是否在第三阶段面临完全相同的问题?

distributed distribution distributed-transactions

16
推荐指数
1
解决办法
2200
查看次数