插入并发问题-多线程环境

2024-05-13

我有一个问题,即使用完全相同的参数在完全相同的时间调用相同的存储过程。

存储过程的目的是获取记录(如果存在)或创建并获取记录(如果不存在)。

问题是两个线程都在检查记录是否存在并报告错误,然后都插入新记录,在数据库中创建重复记录。

我尝试将操作保留在事务中,但这只会产生数百个死锁。

有什么方法可以以线程安全的方式检查记录是否存在,以便第二个线程在第一个线程完成插入之前不会进行读取?我无法控制线程本身,只能控制它们正在执行的存储过程。

任何帮助,将不胜感激,

Thanks.


诀窍是在 INSERT 语句中添加 WHERE,以便 INSERT 仅在该项目不存在时才起作用,后跟 SELECT 语句。假设记录可以通过 ID 列来标识,您可以编写:

INSERT INTO MyTable (ID,Col1,Col2,...) 
SELECT @IDValue,@Col1Value,@Col2Value, ...
WHERE NOT EXISTS (SELECT ID  
              FROM MyTable 
              WHERE ID=@IDValue) 

SELECT *  
FROM MyTable 
Where ID=@IDValue 

您不需要将语句放入事务中,因为每个语句都在其自己的隐式事务中执行。因此,两个插入不可能同时成功。

EDIT:INSERT ... SELECT 语法是必需的,因为 TSQL 不允许在 INSERT 语句中包含 VALUES 和 WHERE 部分。

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

插入并发问题-多线程环境 的相关文章

随机推荐

  • 如何在单个 Razor 视图中编辑多个模型

    我是 MVC3 的新手 我有多个模型 例如BussinessDetails ContactPerson ServiceArea Address以及更多型号 我有一个单一的视图页面 其中共享视图页面如Contacts BusinessDeta
  • 如何在 azure devops 中触发拉取请求的构建和测试?

    我的 git 存储库托管在 devops 内部 我希望在创建拉取请求时构建代码并运行测试 但是我不知道如何做到这一点 我读到了有关拉取请求触发器等的内容 但我不知道如何添加这些触发器 因为似乎没有选项来创建它们 一旦拉取请求完成并合并到主控
  • 光标返回错误值 - sqlite - Android

    我正在开发一个短信应用程序 我正在尝试从每次对话中获取最后一条短信 这是我的 SQL 语句 SELECT MAX smsTIMESTAMP AS smsTIMESTAMP id smsID smsCONID smsMSG smsNUM sm
  • 使用 Maven 配置文件进行工件版本控制

    我希望项目的版本号采用以下格式进行正常发布版本控制
  • PHP:会话 |无法解码会话对象

    我尝试将电子商务功能添加到遗留项目中 因此我仍然需要旧的会话处理程序 我使用 PHP v7 1 14 和 Session2DB https github com voku session2db tree 4 0 0 https github
  • 在 Delphi 2009 上安装最新版本的 Indy 10 [重复]

    这个问题在这里已经有答案了 是否有更新 Delphi 2009 中的 Indy 10 组件的分步指南 我读过正在卸载线程 https stackoverflow com questions 486210 what is the proper
  • 将 .php URL 重定向到不带扩展名的 URL [重复]

    这个问题在这里已经有答案了 可能的重复 使用 htaccess 删除 php 扩展名 https stackoverflow com questions 4026021 remove php extension with htaccess
  • 如何正确使用和实例化现有预览处理程序

    我正在尝试使用现有的预览处理程序来显示文件的预览 我编写了一个简单的测试程序 以 1 查找给定文件的预览处理程序的 CLSID 2 实例化预览处理程序 3 通过流或文件初始化它 4 在基本窗口上渲染预览 这有效 或多或少 It works
  • dalvikvm中Android异常

    当我在手机上启动应用程序时 我从日志中收到很多以下错误 E dalvikvm 2052 No free temp registers E dalvikvm 2052 Jit aborting trace compilation revert
  • 加快写入文件的速度

    我已经分析了一些我用 cProfile 继承的遗留代码 我已经做了很多有帮助的更改 例如使用 simplejson 的 C 扩展 基本上 该脚本将数据从一个系统导出到 ASCII 固定宽度文件 每一行都是一条记录 并且有许多值 每行有 71
  • 如何在嵌入式tomcat中配置valve?

    我需要在嵌入式tomcat中配置valvehttp tomcat apache org tomcat 8 0 doc config valve html Remote IP Valve http tomcat apache org tomc
  • MongoDB 在仅返回 _id 时使用 COLLSCAN

    我想返回 MongoDB 集合中的所有 ID 我使用了以下代码 db coll find id 1 但MongoDB扫描整个集合而不是从默认读取信息index id 1 从日志中 find collection filter project
  • 每第 n 个字符分割一个字符串

    在 JavaScript 中 这就是我们如何在每 3 个字符处分割一个字符串 foobarspam match 1 3 g 我正在尝试弄清楚如何在 Java 中做到这一点 有什么指点吗 你可以这样做 String s 1234567890
  • 在 Delphi 2007 中将具有透明度的位图保存为 PNG

    我有一个包含透明度信息的 Delphi 位图 32 位 我需要将其转换并保存为 PNG 文件 同时保留透明度 我目前拥有的工具是graphics32 Library GR32 PNG 由Christian Budde 提供 和PNGImag
  • 并行启动服务

    我有一个脚本可以检查不同服务器上的某些服务是否已启动 如果没有启动 该脚本应该启动该服务 问题是 它不会并行启动服务 而是等待每个服务启动 Code server list Get Content path D Path list of s
  • Google G-Suite API 控制台未显示启用 G Suite 域范围委派

    我正在与客户合作设置服务帐户凭据 以便通过 API 读取 G Suite 目录信息 我之前已经这样做了十几次 没有任何问题 现在我遇到了一个问题 设置没有向客户端显示 下面的图片显示了我通常会看到的内容 阅读中圈出的区域是启用域范围委派的能
  • 使用 VNext 构建后,TFS tbl_Content 开始快速增长

    直到一个月前我们一直在使用旧样式 XAML 构建 然后开始使用 vNext 构建 之后我注意到 TFS 数据库中的 tbl Content 表开始快速增长 例如 在过去 8 小时内 它增长了 10 GB 但我不明白为什么会这样做 有谁知道它
  • 我可以通过链接分享我的私人 GitHub 存储库吗?

    我在 GitHub 上的私人存储库中有一个 Java 应用程序 我想与没有帐户的人共享它 我在网站上没有找到任何与此相关的选项 有没有办法做到这一点 协作者只能是 GitHub 用户 无法在非 Github 用户之间共享私有存储库 您需要
  • 使用 XPath 3.1 fn:serialize 进行 JSON 序列化

    我在 Saxon HE 9 8 中使用 XSLT 3 0 并且希望将 JSON 文档用作链接数据JSON LD https json ld org 在 JSON LD 中 完整的 HTTP URI 通常显示为值 当我使用 XPath 3 1
  • 插入并发问题-多线程环境

    我有一个问题 即使用完全相同的参数在完全相同的时间调用相同的存储过程 存储过程的目的是获取记录 如果存在 或创建并获取记录 如果不存在 问题是两个线程都在检查记录是否存在并报告错误 然后都插入新记录 在数据库中创建重复记录 我尝试将操作保留