SqlConnection 并避免升级到 MSDTC

2024-04-17

当我们需要在应用程序中进行数据库访问时,我们使用以下模式:

  • 为了查询,我们有一个带有方法的静态工厂类CreateOpenConnection其作用无非是new SqlConnection(myConnectionString)并打电话Open()在上面。在执行查询之前调用此方法,并在查询返回后释放连接。
  • 对于插入/更新/删除,我们使用工作单元模式,其中批处理更改并通过调用提交到数据库work.Commit()像这样:

工作.提交:

using (var tranScope = new TransactionScope(TransactionScopeOption.RequiresNew))
{
    using (var conn = DapperFactory.CreateOpenConnection())
    {
      var count = _changeTracker.CommitChanges(conn);

      tranScope.Complete();

      return count;
    }
}

这似乎非常适合作为 Web 服务的一部分进行一般使用,但目前当我尝试将其与 Rebus 结合使用时,MSDTC 遇到了麻烦。

据我所知,Rebus(当它处理队列中的消息时)创建了一个新的TransactionScope以便在处理消息失败的情况下,可以回滚内容。现在,到目前为止,这本身运行良好。我可以开一个新的SqlConnection在 Rebus 消息处理程序中没有任何问题(但是,使用我们的旧实体框架查询and同一 Rebus 内的手动 SqlConnectionsTransactionScope不起作用,但我现在不认为这是一个问题)。但昨天我问了以下问题:

Rebus中某种消息类型的串行处理 https://stackoverflow.com/questions/16837668/serial-processing-of-a-certain-message-type-in-rebus/16843938#16843938

答案似乎是使用 Rebus 的 saga 功能。我尝试实现这个并对其进行配置,以便将 Rebus 传奇持久化到新的 SQL Server 数据库(具有不同的连接字符串)。据推测,使用 SQL Server 持久性会打开一个SqlConnection它自己的,因为任何时候我尝试创建一个SqlConnection现在,我得到以下异常:

分布式事务管理器 (MSDTC) 的网络访问已被禁用。请使用组件服务管理工具在 MSDTC 的安全配置中启用 DTC 进行网络访问。

启用 MSDTC 是我非常想要的,very在配置和性能开销方面,很想避免这样做。我可能是错的,但这似乎也没有必要。

我认为这里发生的是 Rebus 创建了一个环境TransactionScope并且那SqlConnection它会创建该范围的入伍者。当我尝试创建自己的SqlConnection它还尝试加入该环境范围,并且由于涉及多个连接,因此它被提升为 MSDTC,但失败了。

我有一个关于如何解决这个问题的想法,但我不知道这是否是正确的做法。我要做的是:

  • Add Enlist=false到我的应用程序的连接字符串,以便它永远不会加入环境事务。
  • 修改Commit方法,这样它就不会创建新的TransactionScope(我的连接不会再订阅,因为我只是告诉它不应该)但它使用conn.BeginTransaction.

Like so:

var transaction = conn.BeginTransaction();

try
{
  var count = _changeTracker.CommitChanges(conn);
  transaction.Commit();
  return count;
}
catch
{
  transaction.Rollback();
  throw;
}
finally
{
  transaction.Dispose();
}

我只是不确定这是否是正确的方法以及可能的缺点是什么。

有小费吗?

UPDATE:澄清一下,这不是work.Commit()这一直给我带来问题,我很确定它会起作用,但我从来没有到达那里,因为我的querying就是失败。

失败的例子:

public int? GetWarehouseID(int appID)
{
  var query = @"
select top 1 ID from OrganizationUnits o
where TypeID & 16 = 16 /* warehouse */";

  using (var conn = _dapper.OpenConnection())
  {
    var id = conn.Query<int?>(query).FirstOrDefault();

    return id;
  }
}

TransactionScope是由 Rebus 创建的,也是经过SqlConnection由Rebus打开。打开后my SqlConnection,它尝试加入并崩溃


我对你看到这个感到有些惊讶,因为RequiresNew should意味着它与其他事务隔离;通常,此消息意味着事务范围内已激活 2 个连接 - 您是吗?sure该块内没有其他代码创建/打开连接吗?

您提出的解决方案应该有效 - 尽管在某些方面TransactionScopeOption.Suppress可能比更改配置更方便(但两者都应该有效)。但是,存在一个问题:ADO.NET 事务必须传递给各个命令,因此您需要(还需要稍微整理一下代码):

using(var transaction = conn.BeginTransaction()) {
    try {
        var count = _changeTracker.CommitChanges(conn, transaction);
        transaction.Commit();
        return count;
    } catch {
        transaction.Rollback();
        throw;
    }
}

where CommitChanges接受交易 - 可能使用可选参数:

int CommitChanges(DbConnection connection, DbTransaction transaction = null)
{ ... }

你的命名DapperFactory建议您使用“dapper” - 在这种情况下,您可以将其传递给“dapper”,无论它是否为空,即

conn.Execute(sql, args, transaction: transaction);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SqlConnection 并避免升级到 MSDTC 的相关文章

  • 为什么通过派生类对基类的引用与 :: - 运算符不明确?

    所以我想知道为什么以下钻石问题的代码片段无法编译 我知道这个问题通常是通过虚拟继承来解决的 我不是故意使用它的 该代码只是为了展示我的问题 即为什么编译器称此不明确 因此 我在 struct Base 中声明了两个成员变量 因为这两个子类
  • 编写此代码片段的有效方法是什么? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 更有效和 或更短地重写此代码以节省字节并显得不那么冗长的方法 if N 2 0 N 6 N 8 N 10 N 12 N 14 N 16 N
  • JSON.Net 反序列化返回“null”

    我正在使用 JSON Net 反序列化 JSON 字符串 JSON 字符串是 string testJson Fruits Apple color red size round Orange Pro
  • 如何使用 ASP.NET MVC 编辑多选列表?

    我想编辑一个如下所示的对象 我希望用 UsersGrossList 中的一个或多个用户填充 UsersSelectedList 使用 mvc 中的标准编辑视图 我只得到映射的字符串和布尔值 下面未显示 我在 google 上找到的许多示例都
  • 异常堆栈跟踪不显示抛出异常的位置

    通常 当我抛出异常 捕获它并打印出堆栈跟踪时 我会看到抛出异常的调用 导致该异常的调用 导致该异常的调用that 依此类推回到整个程序的根 现在它只向我显示异常所在的调用caught 而不是它所在的地方thrown 我不明白是什么改变导致了
  • 将下拉列表与字典绑定

    我将字典绑定到下拉列表 举例来说 我的字典中有以下项目 Test1 123 Test2 321 我希望下拉文本采用以下格式 Test1 Count 123 Test2 Count 321 我沿着以下路径走 但没有运气 MyDropDown
  • C 中“complex”的默认类型

    根据我读过的文档 C99 和更高版本的支持float complex double complex and long double complex作为复杂类型 但是 此代码在使用时编译时不会发出警告gcc Wall Wextra inclu
  • while循环中的变量初始化

    我有一个可以分块读取文件的函数 public static DataObject ReadNextFile 数据对象看起来像这样 public DataObject public string Category get set And ot
  • 为什么需要数字后缀?

    C 语言 我确信还有其他语言 需要在数字文字末尾添加后缀 这些后缀指示文字的类型 例如 5m是一个小数 5f是一个浮点数 我的问题是 这些后缀真的有必要吗 或者是否可以从上下文中推断出文字的类型 例如 代码decimal d 5 0应该推断
  • 在 C# 中何时使用 ArrayList 而不是 array[]?

    我经常使用一个ArrayList而不是 正常 array 当我使用时 我感觉好像我在作弊 或懒惰 ArrayList 什么时候可以使用ArrayList在数组上 数组是强类型的 并且可以很好地用作参数 如果您知道集合的长度并且它是固定的 则
  • 你好,我最近正在开发我的新游戏,我遇到了*无限跳跃*的问题

    所以基本上当我按跳跃 空格键时我会跳跃但是如果我连续按空格键它 只是跳啊跳啊跳等等 我不想要我只想它跳一次 code if Input GetKeyDown space isGrounded velocity y Mathf Sqrt ju
  • 通过 C# Mailkit / Mimekit 发送电子邮件,但出现服务器证书错误

    Visual Studio 2015 中的 0 代码 1 我正在使用 Mailkit 最新版本 1 18 1 1 从我自己的电子邮件服务器发送电子邮件 2 电子邮件服务器具有不受信任的自签名证书 3 我在代码中添加了以下两行 以忽略服务器证
  • ALTER TABLE ... ADD CONSTRAINT 失败时将事务回滚到保存点

    有没有办法在事务中添加检查约束and如果失败回滚到以前的保存点 而不是回滚整个事务 就我而言 当 ALTER TABLE ADD CONSTRAINT 命令失败时 事务无法回滚到保存点 尝试这样做会引发 InvalidOperationEx
  • 使用 xslt 将 xml 转换为 xsl-fo 时动态创建超链接?

    我想使用 xsl 文件在 PDF 报告中创建标题 如果源文件包含超链接 则应将其呈现为超链接 否则呈现为纯文本 例如 我的 xml 如下所示 a href http google com target blank This is the h
  • 浮点字节序?

    我正在为实时海上模拟器编写客户端和服务器 并且由于我必须通过套接字发送大量数据 因此我使用二进制数据来最大化可以发送的数据量 我已经了解整数字节顺序以及如何使用htonl and ntohl为了规避字节顺序问题 但我的应用程序与几乎所有模拟
  • Autoconf 问题:“错误:C 编译器无法创建可执行文件”

    我正在尝试使用 GNU 自动工具构建一个用 C 编写的程序 但显然我设置错误 因为当configure运行 它吐出 configure error C compiler cannot create executables 如果我看进去con
  • 有没有办法直接在函数参数中格式化字符串而不是使用临时字符串?

    我有一个接受字符串 字符数组 作为参数的函数 void enterString char my string 当使用这个函数时 我经常发现自己想要输入格式化的字符串 我使用 sprintf 来做到这一点 然而 我每次都必须创建一个临时字符串
  • 如何将 int 作为“void *”传递给线程启动函数?

    我最初有一个用于斐波那契变量数组的全局变量 但发现这是不允许的 我需要进行基本的多线程处理并处理竞争条件 但我无法在 pthread 创建中将 int 作为 void 参数提供 我尝试过使用常量指针 但没有成功 由于某些奇怪的原因 void
  • 将 Swagger 与命名空间版本的 WebApi 结合使用

    我已经找到了如何使用基于名称空间的 WebAPI 版本这个班 https aspnet codeplex com SourceControl changeset view dd207952fa86 Samples WebApi Namesp
  • 嵌入式二进制资源 - 如何枚举嵌入的图像文件?

    我按照中的说明进行操作这本书 http www apress com book view 9781430225492 关于资源等的章节 我不太明白的是 如何替换它 images Add new BitmapImage new Uri Ima

随机推荐

  • 为什么 TableAttribute 位于实体框架 Dll 中?

    Table 属性 可用于将 POCO 类映射到正确的数据库名称 架构 位于 EntityFramework dll 中是否有充分的理由 这是否会阻止您创建一个仅包含您的实体而不依赖于特定数据访问技术的域项目 例如 如果我使用此属性 我不相信
  • CLGeocoder 返回其他国家/地区的位置

    我有以下代码 CLGeocoder geo CLGeocoder alloc init CLRegion region CLRegion alloc initCircularRegionWithCenter CLLocationCoordi
  • 在Sandbox中使用Cocoa NSSavePanel导致断言失败

    我正在尝试使用 NSSavePanel 并将这一行添加到我的代码中 let test NSSavePanel 每次调用此代码时都会出现此错误 我不太确定这里发生了什么 因为我只是创建一个新对象 任何帮助表示赞赏 谢谢 Assertion f
  • 如何在 MVC Core 和 AutoFac 中使用属性注入

    我可以在 MVC Core 中轻松使用构造函数参数注入 但不支持属性注入 我尝试使用 AutoFac 但也失败了 那么如何在MVC Core中使用属性注入 这是 AutoFac 的代码 services AddMvc ContainerBu
  • 使用 Linkify Android 打开 Activity

    我想在用户使用 linkify 单击 textView 时打开 Activity 这是我的代码 Pattern tagMatcher Pattern Compile A Za z0 9 Scheme for Linkify when a w
  • C++ 中的 malloc/free 和 new/delete 兼容性?

    malloc free 和 new delete 有一个很好的比较here https stackoverflow com questions 240212 what is the difference between new delete
  • 致命错误:netinet/in.h:没有这样的文件或目录

    套接字编程 UDP 服务器 我正在尝试使用 UDP 服务器进行消息加密和解密 代码在这里 https www geeksforgeeks org message encryption decryption using udp server
  • 创建一个 python 脚本来安装 python 模块并运行一些命令

    我想围绕这个库创建一个薄包装https github com jupyter incubator sparkmagic installation https github com jupyter incubator sparkmagic i
  • Django - ImportError:无法导入名称 Celery

    这是我第一次使用 celery 我完成了这个教程 将 celery 与 Django 一起使用 http docs celeryproject org en latest django first steps with django htm
  • 如何解码哈希

    如果攻击者可以访问用户的数据库并且密码存储在哈希值中 攻击者可以解码该哈希值吗 您能推荐任何可以解码哈希值的工具吗 您可以在这里找到更多详细信息 http crackstation net hashing security htm http
  • C#/WPF:如何单独显示 ListView 的最后一行?

    我有一个 ListView 其中包含大约 10 个 GridViewColumn 和大约 100 行 行 我想在 ListView 的底部显示 总计 或摘要行 有谁知道如何做到这一点 保持 ColumnWidth 等像其他一样并将其作为一个
  • 在 UITextview 中加载巨大的文本文件会崩溃

    我想更新 UITextView 中的一个巨大的文本文件 但设备有时会挂起或崩溃 文本文件大小为 4MB UITextView 是从 Interface Builder 添加的 我正在从文档目录加载文件 以下是加载文本文件的代码 NSErro
  • 如何从函数返回值 - React Native

    如何从反应本机函数返回布尔值 它可以这样完成 export function isJson str try JSON parse str catch e return false return true 该函数检查提供的值是否有效JSON
  • 检查标准输入缓冲区是否为空

    我正在尝试用字符读取数字字符 但我不知道标准输入缓冲区是否为空 我的第一个解决方案是寻找 n标准输入缓冲区中的字符 但是如果我要输入由分隔符分隔的多个数字 这就没用了 我如何知道标准输入缓冲区中是否有字符 我需要用 C 语言来完成它并且是可
  • 编译后的第一次执行非常慢,除非“明显”所有循环都会停止

    我这个标题的意思是 在某些情况下 构建整个程序后 它的第一次执行将需要大约 25 秒才能开始 直到第一个 printf 在控制台上显示 接下来的执行几乎立即开始 正如它们应该的那样 添加 删除一个空格并再次编译 之后的第一次执行再次变得极其
  • 如何在同一图上显示条形图和折线图

    我无法在同一绘图上显示条形图和折线图 示例代码 import pandas as pd import numpy as np import matplotlib pyplot as plt Df pd DataFrame data np r
  • Python-Selenium 查找不可点击的可点击元素

    我在用python selenium运行自动化测试 在复杂的非公共环境中运行这些测试时 我发现了一些我将标记为 selenium 中的错误的东西 基本上我想做的是在 DOM 中找到一些元素 当它变得可点击时 然后点击它 代码如下 what
  • 处理程序如何/何时被垃圾收集?

    在我的一个类中 我有以下代码 mHandler createHandler private Handler createHandler return new Handler public void handleMessage Message
  • 声明按位运算的掩码

    我是这样的低级操作的新手 我希望有人能指出我在这里犯的明显错误 Input value 00111100 I want to get the value of the bits at indexes 1 3 i e 0111 byte ma
  • SqlConnection 并避免升级到 MSDTC

    当我们需要在应用程序中进行数据库访问时 我们使用以下模式 为了查询 我们有一个带有方法的静态工厂类CreateOpenConnection其作用无非是new SqlConnection myConnectionString 并打电话Open