使用 MSMQ 和 SQL Server 进行分布式事务,但有时会出现脏读

2024-01-22

我们的 SQL Server 2014 数据库设置为READ_COMMITTED_SNAPSHOT.

我们使用 MSMQ 和分布式事务(我们使用 MassTransit 2.10)

在我们系统的一部分中,我们从队列中读取一条消息,进行数据库更新,然后将一条新消息发布到队列(所有这些都在单个事务下)。

我们发现了一种情况,在处理下一条消息时似乎没有提交更新(它从同一个表中读取第一部分更新),即使我希望该消息仅同时存在于队列中数据库已更新。当我们稍后查询该表时,更新的数据将按预期存在。这种情况似乎只发生在我们负载较高的情况下,而且很少发生。

我们的代码的简化版本

// code that processes message 1
using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions() { Timeout = TimeSpan.FromMinutes(30), IsolationLevel =  IsolationLevel.ReadCommitted }) 
{
     MethodThatUpdatesTableX();
     MethodThatCreatesMessage2();
     scope.Complete();
}    

// message picked up from MSMQ and then (this runs in different thread):
// code that process message 2
using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew,  new TransactionOptions() { Timeout = TimeSpan.FromMinutes(30), IsolationLevel = IsolationLevel.ReadCommitted }) 
{
     MethodThatReadsFromTableX(); // so here it seems that changes made in MethodThatUpdatesTableX is sometimes (though rarely) not read
    // other stuff
}    

所以这是我的理解:

当范围被释放时,对表 X 的更改将被提交,消息也会发布到队列中

When MethodThatReadsFromTableX()从表 X 读取我希望更改存在(在第一个会话完成之前不应创建会话,因为它将无法从队列中获取消息)

我的期望正确吗?可能是什么问题?


以下是我对这个问题的思考。

在分布式事务中,通常使用两阶段提交。在第一阶段,交易协调员要求每个人做好承诺的准备。如果每个人都同意,在第二阶段协调员将命令每个人提交更改。请注意,当节点在此阶段提交更改时,它将不再回滚。另请注意,参与者 A(例如 Sql 服务器)和实际提交更改的参与者 B (MSMQ) 之间可能存在不可避免的间隙。当 MSMQ 已经提交更改时,SQL Server 可能还没有提交(尽管已经收到命令)。

因此,当 MSMQ 提交事务时,没有什么可以阻止创建的消息传递到您的处理器,正如您所说,它在另一个线程中运行。因此,即使在您离开第一个“范围”块之前 - 您的处理器可能会开始处理收到的消息,并且 SQL Servermight尚未提交更改。分布式事务无法阻止这种行为,因为它无法以某种方式强制每个参与者在完全相同的时间完成提交其更改。

长话短说 - 我认为它按预期工作,您应该做好准备,在处理 MSMQ 消息并实现重试逻辑时,可能会丢失所需的数据。

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

使用 MSMQ 和 SQL Server 进行分布式事务,但有时会出现脏读 的相关文章

随机推荐

  • 在 Nexus 上使用 nuget 代理时,dotnet 恢复失败

    我在内部网络的 Nexus v 3 9 0 01 上有一个 nuget 代理 我自己还没有填充本地 Nexus 存储库 并且不知道它是如何完成的或是否出现任何问题 但是 我可以手动上传新包 构建在 Bamboo 代理上进行 无法连接到公共存
  • 如何将 Scala 脚本拆分为多个文件

    作为脚本语言 Scala 是否有某种 include 指令 或者有没有办法从其他脚本启动脚本 The scala命令有 load filename命令以交互方式加载 Scala 文件 或者 scala命令的 i filename参数可用于预
  • Android 中的 Viewpager 底部有固定选项卡,每个选项卡中有图标和文本

    我想创建以下布局 一个带有 viewpager 的活动以及一个选项卡 该选项卡保留在活动的底部以指示用户位于 4 个片段中的哪一个 并且所选选项卡通过 活动颜色 突出显示 我花了一些时间在网上查看各种资源来添加此选项卡 http devel
  • 更好地使用验证或离开事件来验证文本框数据?

    在为 VB NET 文本框编写验证逻辑时 最好使用哪个事件处理程序 证实 or Leave 据我了解 它们是同时发生的 然而 根据这篇文章 MSDN Control Leave 事件 http msdn microsoft com en u
  • CSS 网格。隐藏未使用的区域

    我有基于已知元素构建的网格模板区域 但并非所有元素都可以从数据库中获取 如果我没有从数据库中获取某些内容 那么我不会渲染 html 元素 并且会得到一个带有间隙的空 虚线 行 请参阅附图 空行位于蓝色框下方 是否可以隐藏未使用的区域或消除其
  • 如何使用 avx 指令将 float 向量转换为短整型?

    基本上我如何使用 AVX2 内在函数编写与此等效的内容 我们在这里假设result in float属于类型 m256 while result属于类型short int or short int 8 for i 0 i lt 8 i re
  • 关于Javascript注入的问题

    我一直在 asp net mvc 学习网站上阅读有关 JavaScript 注入的内容 这真是令人大开眼界 我什至从未意识到 想过有人使用 JavaScript 来进行一些奇怪的屁股注入攻击 然而 它给我留下了一些悬而未决的问题 First
  • 使用Python请求获取html?

    我正在尝试自学一些基本的网络抓取 使用 Python 的 requests 模块 我能够抓取各种网站的 html 直到我尝试了以下方法 gt gt gt r requests get http www wrcc dri edu WRCCWr
  • 如何使用变量来引用代号一中的组件?

    我使用 UIBuilder 创建了一个 UI 而不是总是使用findXXXX 我很乐意在Statemachine public class Statemachine private Container c private Tabs t in
  • 是否可以在 launchSettings.json 中引用环境变量?

    我想使用 NuGet 包中的可执行文件来运行我的代码 因此 该 exe 位于我的用户配置文件目录中 所以 该文件看起来像这样 profiles UITests commandName Executable executablePath C
  • 如何在 iOS Safari 上设置渐变背景透明度?

    以下 CSS 在 Safari 上不起作用 在 iPad iOS 上测试 map left navi background ffffff background moz linear gradient left ffffff 35 trans
  • 列表对象没有属性副本

    feed obj self get feed obj request kwargs get feed id ad ingredient id kwargs get ad ingredient id adingredient obj AdIn
  • 使用 tabulate Python 包生成正确的 LaTeX 表

    我正在使用tabulate https pypi python org pypi tabulate 用于生成正确 LaTeX 格式的表格的 Python 包 这是一个 MWE from tabulate import tabulate ta
  • 获取当前正在执行的 Javascript 的 URL

    我正在尝试查找当前正在执行的 javascript 的 url 我知道我可以使用window location href对于当前页面 但这不一定是正在执行的脚本的路径 任何帮助是极大的赞赏 Thanks EDIT 1 我完全愿意使用插件等来
  • 没有规则为“macosx10.10”创建目标 SDK 路径

    我使用的是mac osx10 10 QT5 4 VTK6 2 运行我的代码时出现以下错误 make 2 没有规则可以创建目标 Applications Xcode app Contents Developer Platforms MacOS
  • 获取 setState 不是一个函数

    我收到以下错误 bundle js 31367 未捕获类型错误 this setState 不是 功能 JSX componentDidMount ajax url http intelligencevillage wxtui cn ind
  • 从变量目标 c 中插入换行符

    我正在使用 xml 将数据拉入我的 iphone 应用程序 然后将 xml 值放入变量中 示例变量 123 London road n London n England 然后将该变量设置为标签 我希望换行符出现在标签中 而不是打印 n 如果
  • 是否可以使用 Spring API Gateway 进行威胁防护?

    我将使用 Netflix Zuul 实现 API 网关 是否可以设置任何规则来防止 SQL注入 XML 威胁防护 JSON 威胁防护 我发现只有外部解决方案 API 网关 支持它 None
  • 带有附加 SDK 的 Firefox 中的自定义上下文菜单?

    我希望向显示的 Firefox 上下文菜单添加一个菜单项 仅当用户右键单击特定 URL 时 我有一个测试 url 的函数 我曾经通过订阅 popupshowing 事件来做到这一点 var item document getElementB
  • 使用 MSMQ 和 SQL Server 进行分布式事务,但有时会出现脏读

    我们的 SQL Server 2014 数据库设置为READ COMMITTED SNAPSHOT 我们使用 MSMQ 和分布式事务 我们使用 MassTransit 2 10 在我们系统的一部分中 我们从队列中读取一条消息 进行数据库更新