问题标签 [transactionscope]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
7 回答
77445 浏览

c# - TransactionScope 在某些机器上自动升级到 MSDTC?

在我们的项目中,我们使用 TransactionScope 来确保我们的数据访问层在事务中执行它的操作。我们的目标是不需要在最终用户的机器上启用 MSDTC 服务。

问题是,在我们一半的开发人员机器上,我们可以在禁用 MSDTC 的情况下运行。另一半必须启用它,否则他们会收到“[SERVER] 上的 MSDTC 不可用”错误消息。

这真的让我摸不着头脑,并让我认真考虑回滚到基于 ADO.NET 事务对象的类似 TransactionScope 的自制解决方案。这看起来很疯狂 - 在我们一半开发人员的工作(并且不会升级)的相同代码确实会升级到其他开发人员的代码。

我希望有一个更好的答案来跟踪为什么交易会升级到 DTC,但不幸的是它没有。

这是会导致问题的示例代码,在尝试升级的机器上,它会尝试在第二个连接上升级。Open()(是的,当时没有其他连接打开。)

我们真的深入研究并试图解决这个问题。以下是有关它工作的机器的一些信息:

  • 开发 1:Windows 7 x64 SQL2008
  • 开发 2:Windows 7 x86 SQL2008
  • 开发 3:Windows 7 x64 SQL2005 SQL2008

它不适用于的开发人员:

  • 开发 4:Windows 7 x64,SQL2008 SQL2005
  • 开发 5:Windows Vista x86、SQL2005
  • 开发 6:Windows XP X86、SQL2005
  • 我的家用电脑:Windows Vista Home Premium、x86、SQL2005

我应该补充一点,为了解决问题,所有机器都已使用 Microsoft Update 提供的所有内容进行了全面修补。

更新1:

该 MSDN 事务升级页面指出,以下情况将导致事务升级到 DTC:

  1. 在事务中登记了至少一个不支持单阶段通知的持久资源。
  2. 事务中至少包含两个支持单阶段通知的持久资源。例如,征用单个连接不会导致事务被提升。但是,每当您打开导致数据库登记的第二个数据库连接时,System.Transactions 基础结构会检测到它是事务中的第二个持久资源,并将其升级为 MSDTC 事务。
  3. 调用将事务“编组”到不同应用程序域或不同进程的请求。例如,跨应用程序域边界的事务对象的序列化。事务对象是按值编组的,这意味着任何跨应用程序域边界(即使在同一进程中)传递它的尝试都会导致事务对象的序列化。您可以通过调用将事务作为参数的远程方法来传递事务对象,也可以尝试访问远程事务服务组件。这会序列化事务对象并导致升级,就像跨应用程序域序列化事务时一样。它正在分发,本地事务管理器不再足够。

我们没有遇到#3。#2 没有发生,因为一次只有一个连接,而且它也连接到一个“持久资源”。#1 有没有可能发生?某些 SQL2005/8 配置导致它不支持单阶段通知?

更新 2:

重新调查了一下,个人,大家的SQL Server版本——“Dev 3”居然有SQL2008,“Dev 4”其实是SQL2005。这将教会我永远不要再信任我的同事。;) 由于数据的这种变化,我很确定我们已经找到了我们的问题。我们的 SQL2008 开发人员没有遇到这个问题,因为 SQL2008 包含大量的很棒的内容,而 SQL2005 没有。

它还告诉我,因为我们将支持 SQL2005,所以我们不能像以前那样使用 TransactionScope,如果我们想使用 TransactionScope,我们将需要传递一个 SqlConnection 对象......在 SqlConnection 不能轻易传递的情况下,这似乎是有问题的……它只是闻到了 global-SqlConnection 实例的味道。座位!

更新 3

只是为了澄清问题:

SQL2008:

  • 允许单个 TransactionScope 内的多个连接(如上面的示例代码所示。)
  • 注意事项 #1:如果这多个 SqlConnections 是嵌套的,即同时打开两个或多个 SqlConnections,TransactionScope 将立即升级为 DTC。
  • 警告 #2:如果一个额外的 SqlConnection 被打开到不同的“持久资源”(即:不同的 SQL Server),它将立即升级到 DTC

SQL2005:

  • 不允许单个 TransactionScope 期间内的多个连接。当/如果打开第二个 SqlConnection 时,它将升级。

更新 4

为了使这个问题更加有用,并且为了更清楚起见,以下是如何让 SQL2005 升级为 DTC 的方法 SqlConnection

这对我来说似乎很糟糕,但我想我可以理解是否每次调用SqlConnection.Open()都是从连接池中获取的。

“不过,为什么会发生这种情况呢?” 好吧,如果您在打开该连接之前对它使用 SqlTableAdapter,则 SqlTableAdapter 将打开和关闭连接,从而有效地为您完成事务,因为您现在无法重新打开它。

因此,基本上,为了成功使用 SQL2005 的 TransactionScope,您需要有某种全局连接对象,该对象从第一个 TransactionScope 实例化的那一刻起保持打开状态,直到不再需要它为止。除了全局连接对象的代码异味之外,先打开连接后关闭它与尽可能晚打开连接并尽快关闭它的逻辑相矛盾。

0 投票
4 回答
3311 浏览

c# - 即使 System.Transactions.TransactionScope.Commit() 未调用,数据也已提交

在什么情况下可以将代码包裹在System.Transactions.TransactionScope静止提交中,即使抛出异常并且最外层范围从未调用过提交?

有一个包含在 中的顶级方法using (var tx = new TransactionScope()),它调用的方法也TransactionScope以相同的方式使用。

我正在使用带有关联表适配器的类型化数据集。可能是适配器中的命令由于某种原因没有登记吗?你们有谁知道如何检查他们是否在环境 TransactionScope 中登记?

0 投票
2 回答
1520 浏览

c# - 高级 System.Transactions 调试

是否有任何提示、技巧或方法可以获取有关运行时行为的分析/日志记录/调试信息System.Transactions.TransactionScope

我有一个将数据提交到数据库的应用程序,即使我正在使用System.Transactions.TransactionScope,其中会引发异常并且TransactionScope.Commit()从不调用。

我想知道是否有关于其他类使用的事件或详细信息TransactionScope,我可以在运行时查询以确定我的命令(类型化数据适配器)是否正在征用环境事务。

看过System.Transactions.dll使用 Reflector 后,我认为System.Transactions.Diagnostics命名空间可能会有所帮助,但任何示例都将不胜感激。

0 投票
1 回答
1138 浏览

c# - MS States remote proc trans 选项将在 SQL SERVER 的下一个版本中删除

不知道在这里问是否合适...我在网上搜索了答案,但是徒劳无功...所以我只是想在这里碰碰运气。

这是微软网站http://msdn.microsoft.com/en-us/library/ms189322(SQL.90).aspx的摘录

远程 proc trans 选项

使用 remote proc trans 选项通过 Microsoft 分布式事务协调器 (MS DTC) 事务保护服务器到服务器过程的操作。将 remote proc trans 设置为 1 以提供 MS DTC 协调的分布式事务,以保护事务的 ACID(原子、一致、隔离和持久)属性。将此选项设置为 1 后开始的会话继承配置设置作为其默认设置。

此功能将在 Microsoft SQL Server 的下一版本中删除。避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序。

提供此选项是为了与使用远程存储过程的应用程序的早期版本的 Microsoft SQL Server 兼容。不要发出远程存储过程调用,而是使用引用链接服务器的分布式查询,这些链接服务器是使用 sp_addlinkedserver 定义的。

这是否意味着,我们需要避免在将事务范围对象提升为 MSDTC 的情况下使用它?

注意:这是 SQL Server 2005 的消息,但 SQL Server 2008 也会出现相同的消息。

0 投票
3 回答
7356 浏览

.net - 使用 TransactionScope 和 MS DTC 时的常见问题

我刚刚开始使用 TransactionScope,我发现我总是遇到一些意想不到的事情,需要永远调试。

我认为拥有这些综合列表对于那些“奇怪的错误”情况非常有用,并且可以扩展我们对平台中奇怪的知识。

关于我将如何使用事务范围的一些上下文:

  • Web应用程序
  • 多个 Web 服务器、应用程序服务器和 sql 服务器
  • 事务将主要是数据库事务,但有些事务将被提升以写入 MSMQ。
0 投票
1 回答
1088 浏览

oracle - 处理“异步”提交的好方法是什么?

我有一个 WCF 服务,它使用ODP.NET从 Oracle 数据库中读取数据。该服务也写入数据库,但间接地,因为所有更新和插入都是通过我通过 COM+ 访问的旧业务逻辑层实现的,我将其包装在TransactionScope中。旧层通过 ODBC 而不是 ODP.NET 连接到 Oracle。

我遇到的问题是,因为 Oracle 使用两阶段提交,并且由于较旧的业务层使用的是 ODBC 而不是 ODP.NET,所以事务有时会TransactionScope.Commit()在数据实际可用于从服务层读取之前返回。

我在 Stack Overflow 上看到了一个类似的帖子,关于一个 Java 用户遇到这样的问题。

Oracle 的一位代表发帖称,我对这个问题无能为力:

这可能是由于 OLETx ITransaction::Commit() 方法的行为方式。在 2PC 的第 1 阶段(即准备阶段)之后,如果一切成功, 即使资源管理器实际上还没有提交,提交也可以返回. 毕竟,成功的“准备”是保证资源管理器在此之后不能任意中止。因此,即使资源管理器因为没有收到来自 MSDTC 的“提交”通知(由于通信失败)而无法提交,组件的提交请求也会成功返回。如果您立即从表中选择行,您有时可能会在执行选择后看到实际提交发生在数据库中。因此,由于一致的读取语义,您的选择将不会看到新行。在 Oracle 中我们对此无能为力,因为“在第 1 阶段成功后提交成功”优化是 MSDTC 实施的一部分。

所以,我的问题是:

我应该如何处理可能的延迟(通过标题“asyc”)的问题,以确定 2PC 的第二部分何时实际发生,所以我可以确定我插入(间接)的数据实际上可以被选择Commit()通话返回后?

大型系统如何处理数据可能无法立即读取的事实?

0 投票
1 回答
79 浏览

sql-server-2008 - .Net 2.0 应用程序中的事务——使用什么?

我正在开发一个 .Net 2.0 应用程序,需要在我的代码中包装一些数据库事务。后端是 SQL Server 2008。

我已经离开 .net 几年了,我最后一次进行任何事务处理是在 .Net 1.1 中使用服务组件。我知道 TransactionScope,并且想知道这是否是现在处理事情的好方法。

此外,在 .Net 3.5 中,我假设还有其他方法可以做到这一点,比如 WCF?只是想知道是否有人可以将我指向一两篇文章。非常感谢。

0 投票
1 回答
515 浏览

vb.net - 实例化 TransactionScope 返回 null

我有一些创建 TransactionScope 实例的 VB.NET 代码:

我的应用程序在调用创建新 TransactionScope 时抛出异常,“对象引用未设置为对象的实例。”。我的开发机器或测试机器上没有抛出异常;只在客户的生产机器上,我不知道为什么。我已经在这条线之前和之后放置了调试线,所以我很肯定是这条线导致了问题。

A 在整个应用程序中都使用了 TransactionScopes,这是在客户端计算机上引发异常的唯一地方。

“关于将呼叫数据与合同相关联”被写入日志,下一个日志条目是“对象引用未设置为对象的实例”。

如果我将其移出事务,代码可以正常工作。

我已经为此苦苦挣扎了 4 天,而且还没有接近。

0 投票
1 回答
6624 浏览

ado.net - 在 TransactionScope 中使用 ADO.Net 事务?

我一直在阅读有关 TransactionScope 的内容,并且对它与 ADO.Net 事务的互操作性有疑问。现在我们有一些数据访问方法,每个方法都调用一个存储过程并开始和提交他们自己的单独事务。直截了当,样板的东西,方法如下所示:

我已经简化了一些事情,但你明白了。

我现在需要连续调用其中两个类方法,并将它们作为一个团队从我的业务层提交或回滚。我不能修改数据方法,所以我想把这两个调用放在一个 TransactionScope 块中。

如果我这样做,在创建 TransactionScope 时应该使用什么样的参数?我已经使用 TransactionScopeOption.RequiresNew 选项进行了尝试,并且一切似乎都有效,但这只是我的实验,我不确定这是否是可行的方法。(我会在这里指出,这些是专门的 SQL 事务,在同一个 SQL 服务器上运行。)

我看到 TransactionScope 具有处理 COM+ 事务的构造函数选项。因为我使用的是 ADO.Net 事务,所以这与这里有关吗?感谢您的建议。

0 投票
1 回答
1288 浏览

c# - 即使第二次服务错误,TransactionScope 也允许部分更新

我对相关问题和实施的建议进行了很好的搜索,但我仍然对 .NET TransactionScope 有疑问。

我从一个方法调用两个 WCF 服务,即使第二个服务错误(在这种情况下是故意的),第一个服务也不会回滚。我创建了一个简单的测试应用程序来演示这个问题。

下面是调用方法:

第一个服务看起来像这样(匿名连接):

第二个服务与第一个服务相同,只是它更新数据库中的不同字段。

1)如果我在没有强制错误的情况下运行它,它会更新所有字段。

2)当我运行这个并在第二个服务中强制出错时,第一个服务的更新被提交到数据库,而第二个服务被回滚(错误是在 ExecuteNonQuery 语句之后)。

此示例代码基本上遵循此处找到的示例:http: //msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx

我添加了 Explicit Unbind,这是在其他相关问题中推荐的。

非常欢迎您提出建议 - 如果需要,我很乐意添加更多信息。

额外的信息

分布式标识符似乎始终是 00000000-0000-0000-0000-000000000000 - 我不知道这是否是一个线索。

这是分布式 id 和本地 id 的 dubug 输出(按此顺序)

当前交易是 00000000-0000-0000-0000-000000000000 - f6446876-496d-488c-a21c-1e4c4295d50c:8

当前交易是 00000000-0000-0000-0000-000000000000 - 7edd5ba3-7f5a-42af-b9ca-37b3862c26a7:2

当前交易是 00000000-0000-0000-0000-000000000000 - 6fa0e3f7-b655-40ad-8bdd-f0670de79a49:2

事务是通过我的示例应用程序中的 aspx 页面后面的代码启动的。