以原子方式标记并返回数据库中的一组行

2023-11-26

我正在编写一个后台服务,需要处理一系列作业,这些作业作为记录存储在 sqlserver 表中。该服务需要找到最旧的 20 个需要工作的工作(where status = 'new'),标记它们(set status = 'processing'),运行它们,然后更新作业。

这是我需要帮助的第一部分。可能有多个线程同时访问数据库,我想确保“标记和返回”查询以原子方式运行,或几乎如此。

该服务将花费相对较少的时间访问数据库,并且如果一个作业运行两次也不是世界末日,因此我可能能够接受小概率的作业运行多次,以提高代码的简单性。

做这个的最好方式是什么?我在数据层使用 linq-to-sql,但我想我必须为此使用 t-sql。


你的工作表是一个队列。写入用户表备份队列是出了名的容易出错,因为它会导致死锁和并发问题。

最简单的事情是删除用户表并使用 truequeue反而。这将为您提供经过系统测试和验证的代码库上的无死锁并发队列。问题是围绕队列的整个范例从 INSERT 和 DELETE/UPDATE 更改为SEND/RECEIVE。另一方面,通过内置队列,您可以获得一些非常强大的免费好东西,即激活 and 相关项目锁定.

如果您想继续沿着用户表支持的队列的路径前进,那么second编写用户表队列最重要的技巧是使用 UPDATE ... OUTPUT:

WITH cte AS (
  SELECT TOP(20) status, id, ...
  FROM table WITH (ROWLOCK, READPAST, UPDLOCK)
  WHERE status = 'new'
  ORDER BY enqueue_time)
UPDATE cte
  SET status = 'processing'
OUTPUT
  INSERTED.id, ...

CTE语法只是为了方便正确放置TOP和ORDER BY,查询可以使用派生表编写,就像简单的那样。您不能直接使用 UPDATE ... TOP 因为 UPDATE 不支持 ORDER BY 并且您需要它来满足您的要求的“最旧”部分。需要锁提示来促进并行处理线程之间的高并发性。

我说这是第二重要的技巧。最重要的是如何组织表格。对于队列来说must被聚类为(status, enqueue_time)。如果你没有正确地组织表格,你最终会陷入死锁。先发制人的评论:碎片在这种情况下是无关紧要的。

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

以原子方式标记并返回数据库中的一组行 的相关文章

随机推荐

  • Python 类丢失属性

    我有一个特殊的 python 问题 在我的 gtk python 应用程序执行过程中 我的一些类对象神秘地丢失了属性 导致我的程序的一些功能被破坏 很难解释为什么会发生这种情况 我从来没有故意删除属性 并且有问题的类继承自我自己编写的类 而
  • Android - 在webview中登录后提取cookie

    我有一个在 web 视图中打开 url 的应用程序 然后用户必须通过 web 视图登录到站点并在登录后收到 cookie 我在登录后获取 cookie 时遇到问题 问题是 我可以使用 android webkit CookieManager
  • 在 Angular 5 项目中创建 Web 配置文件?

    我创建了一个 Angular 5 网站 我想使用 Webform 或 MVC 部署给客户 我只想更改 webconfig 文件中的一些变量 dbconnection 名称等 但使用 Angular 我不知道如何去做吧 那么每次部署的时候都得
  • 如何防止 Jetpack Compose 中不必要的重组

    我有一个TextField对于搜索查询和Button这将执行搜索 结果显示在列中 由于搜索需要几秒钟才能运行 我希望它在按下按钮时执行 而不是在文本更改时执行 这是一个简化的演示 Column val list remember mutab
  • 活动页面和背景页面

    由于 Chrome 扩展文档中没有明确的解释 所以我来这里寻求帮助 我了解到 背景页面基本上是为了延长扩展的生命周期而发明的 旨在保存值或保持 引擎 在后台运行 这样就没有人注意到它 因为一旦您单击扩展程序的图标 您就会看到他们所说的 弹出
  • 意外异常:SQLSTATE[HY000] [1045] 用户 ****@'localhost' 的访问被拒绝(使用密码:YES)

    一位老同事交给我一个申请来管理 但是 每当我尝试运行它时 我都会收到此错误 请任何帮助都可以 有时访问被拒绝异常错误 因为您的 mysql 凭据无效 其次 根据我的经验 我观察到这种情况也会发生 因为您没有为数据库连接设置密码 例如 pri
  • 如何从shared_ptr调用私有析构函数?

    我有一个resource manager类维护一个std vector
  • WCF 服务 netTCP 绑定

    我想使用 netTCPbinding 所以我改变了我的网络配置 如下所示 我遇到这个错误 找不到与绑定 NetTcpBinding 的终结点的方案 net tcp 相匹配的基地址 注册的基地址方案是 http 如何解决这个问题
  • 如何从 NodeJS 服务器向客户端发送信息?

    例如 我想向客户端发出信号 表明通过 POST 方法以 HTML 表单发送的用户名已存在于我的数据库中 我知道如何使用 body parser 恢复 POST 数据 并且知道如何在 MySQL 数据库中查找它 我知道我可以使用 Ajax 直
  • 如何在 Java 中获得 UNIX 正常运行时间?

    在 Java 中获得 UNIX 正常运行时间的最佳方法是什么 是否有我可以使用的标准 Java 库 函数 或者我应该使用 Runtime 的 exec 或 ProcessBuilder 来执行 正常运行时间 谢谢 你可以阅读 proc up
  • Azure Web 角色上的 WaitHandleCannotBeOpenedException 以 Task.Wait() 开头

    以下 Web 角色入口点返回后会导致引发以下异常 public class WebRole RoleEntryPoint public override bool OnStart Task Run gt Anything can be he
  • javascript 错误:无法在“文档”上执行“elementsFromPoint”:提供的双精度值是非有限的

    我最近将我的 chrome 版本更新到最新版本 即79 0 3945 130 Official Build 64 bit 并从下载兼容的 chromedriverhere 我已经开始面临这个错误了 在详细调试时我发现Select导致问题的类
  • python csv只写入某些字段名称,而不是全部

    我一定错过了一些东西 但我不明白 我有一个 csv 它有 1200 个字段 我只对 30 感兴趣 你如何让它发挥作用 我可以读 写整个 shebang 这没关系 但我真的很想写出 30 我有一个字段名列表 我有点修改标题 我将如何翻译下面以
  • 如何清除点击时的数据列表输入?

    我在 Lit Element Web 组件中有这个数据列表
  • C++:如何将字符串拆分为大小均匀的较小字符串?

    在 C 中 如何将字符串拆分为大小均匀的较小字符串 例如 我有一个字符串 012345678 并希望它将它分成 5 个较小的字符串 这应该返回类似 01 23 45 67 8 的内容 我无法确定较小字符串的长度 在上一个示例中 原始字符串的
  • 调整织物矩形大小而不调整文本框大小

    In this jsFiddle我有一个包含矩形和文本框的结构组 我需要能够在不缩放文本的情况下缩放矩形 因此我尝试在选择组时取消分组 并在清除选择时再次分组 还 矩形和文本框被分组以便能够将它们一起移动 文本需要可编辑 文本需要位于矩形的
  • MySQL 不更新 information_schema,除非我手动运行 ANALYZE TABLE `myTable`

    我需要获取表 InnoDB 的最后一个 id 主键 为此我执行以下查询 SELECT SELECT AUTO INCREMENT FROM information schema TABLES WHERE TABLE SCHEMA mySch
  • 角度键值管道排序属性/按顺序迭代

    使用角度时keyvalue管道来迭代对象的属性 如下所示 div item key item value div 我遇到过一个问题 即属性未按预期顺序迭代 此评论表明我不是唯一遇到此问题的人 如何在 Angular 中使用 ngFor 循环
  • EditText 文本属性下方有下划线

    我想更改编辑文本下方的蓝色 我不知道它是什么属性 我尝试为其使用不同的背景颜色 但它不起作用 我在下面附上了一张图片 实际上 以编程方式设置 EditText 的下划线颜色相当容易 只需一行代码 设置颜色 editText getBackg
  • 以原子方式标记并返回数据库中的一组行

    我正在编写一个后台服务 需要处理一系列作业 这些作业作为记录存储在 sqlserver 表中 该服务需要找到最旧的 20 个需要工作的工作 where status new 标记它们 set status processing 运行它们 然